Merge ~enr0n/ubuntu-release-upgrader:ubuntu/main into ubuntu-release-upgrader:ubuntu/main

Proposed by Nick Rosbrook
Status: Merged
Merged at revision: d1b30f03a797a1d37c2622ad8ddff858dced9d4a
Proposed branch: ~enr0n/ubuntu-release-upgrader:ubuntu/main
Merge into: ubuntu-release-upgrader:ubuntu/main
Diff against target: 362 lines (+153/-20)
7 files modified
DistUpgrade/DistUpgradeController.py (+9/-0)
DistUpgrade/DistUpgradeQuirks.py (+111/-4)
DistUpgrade/DistUpgradeVersion.py (+1/-1)
data/mirrors.cfg (+8/-10)
debian/changelog (+12/-0)
utils/demoted.cfg (+6/-3)
utils/demoted.cfg.jammy (+6/-2)
Reviewer Review Type Date Requested Status
Brian Murray Approve
Gunnar Hjalmarsson Approve
Review via email: mp+452304@code.launchpad.net

Description of the change

Fix several bugs in ubuntu-release-upgrader. This extends/replaces https://code.launchpad.net/~gunnarhj/ubuntu-release-upgrader/+git/ubuntu-release-upgrader/+merge/451815.

To ease review, I purposely left out the pre-build.sh stuff and debian/changelog, because I will do that when I upload.

To post a comment you must log in.
Revision history for this message
Gunnar Hjalmarsson (gunnarhj) wrote :

Hi Nick,

I have only had a brief look at it so far, but can't help wondering:

When I struggled with the other MP, I found that setting DBUS_SESSION_BUS_ADDRESS and using subprocess instead of Gio.Settings were needed to make it work. Can you tell what the 'secret' is, or was i simply mistaken as regards those details?

Revision history for this message
Nick Rosbrook (enr0n) wrote (last edit ):

DBUS_SESSION_BUS_ADDRESS is set in do-release-upgrade, so it is set correctly in this spot when the upgrade is run "for real". When you test manually, you are entering at a different place (i.e. do-release-upgrade is not executed directly), so you need to set in manually, e.g.

sudo env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus ./mantic

Revision history for this message
Gunnar Hjalmarsson (gunnarhj) wrote :

Thanks for that explanation. As regards Gio I see that you used "settings.sync()" which I didn't. Maybe that's it. Or not, see below.

I have a couple of observations on the part of the code I understand. :/

The partition() method does not safely split the value into font family and size. It ought to work for e.g. 'Ubuntu 11', since the family is one single word, but it didn't work for me when testing. I had set 'Ubuntu 14' and it switched to 'Sans 11'.

=> This makes we wonder if the fetching of the user value is at all successful.

(And it would safely fail if the user value was e.g. 'Liberation Sans 12'.)

Another thing is that you use "settings.get_string" to grab the user font. That should give you a string irrespective of whether there actually is a specific user value or not. If not it gives you the system default ('Ubuntu 11' in standard Ubuntu).

In the equivalent variant of my code I used "settings.get_user_value" instead, which gives you None if there is no specific user value, which means that you can reset it with "gsettings reset".

With your way, the user dconf database will always get a font-name value even if there was no such value when the upgrade started. Maybe subtle and not so important...

review: Needs Fixing
Revision history for this message
Nick Rosbrook (enr0n) wrote :

> Thanks for that explanation. As regards Gio I see that you used
> "settings.sync()" which I didn't. Maybe that's it. Or not, see below.
>
> I have a couple of observations on the part of the code I understand. :/
>
> The partition() method does not safely split the value into font family and
> size. It ought to work for e.g. 'Ubuntu 11', since the family is one single
> word, but it didn't work for me when testing. I had set 'Ubuntu 14' and it
> switched to 'Sans 11'.

Ah yes, this should be changed. I will test the font size issue, but obviously that's not the intention.
>
> => This makes we wonder if the fetching of the user value is at all
> successful.
>
> (And it would safely fail if the user value was e.g. 'Liberation Sans 12'.)
>
> Another thing is that you use "settings.get_string" to grab the user font.
> That should give you a string irrespective of whether there actually is a
> specific user value or not. If not it gives you the system default ('Ubuntu
> 11' in standard Ubuntu).
>
> In the equivalent variant of my code I used "settings.get_user_value" instead,
> which gives you None if there is no specific user value, which means that you
> can reset it with "gsettings reset".
>
> With your way, the user dconf database will always get a font-name value even
> if there was no such value when the upgrade started. Maybe subtle and not so
> important...
In the general case, get_string('font-name') should give the same as get_user_value('font-name').get_string(), and if not I think getting the system default is the right thing to do.

Revision history for this message
Gunnar Hjalmarsson (gunnarhj) wrote :

On 2023-09-28 15:42, Nick Rosbrook wrote:
> In the general case, get_string('font-name') should give the same as
> get_user_value('font-name').get_string(), and if not I think getting
> the system default is the right thing to do.

Well, I'd say that the general case is that the user did not change the desktop font, so my belief is that they differ more often than not.

But this is a detail I'm not going to argue about more.

Revision history for this message
Nick Rosbrook (enr0n) wrote :

Alright, yeah I was missing something with the Gio.Settings approach, so shelling out to gsettings seems the way to go. I did this with `systemd-run --user -M $user@.host ...` to simplify the permissions/user env. That way, there is no need to change our running env or EUID -- just need to get the original UID via SUDO_UID or PKEXEC_UID.

Revision history for this message
Gunnar Hjalmarsson (gunnarhj) wrote :

TMTOWTDI. :) Looking forward to next variant.

Revision history for this message
Nick Rosbrook (enr0n) wrote :

> TMTOWTDI. :) Looking forward to next variant.

It was already pushed.

Revision history for this message
Gunnar Hjalmarsson (gunnarhj) wrote :

This looks good to me now. Didn't know that the rpartition() method existed, but it fits well in this context. And it did The Right Thing for me when testing.

Thanks for your work, and especially the idea to postpone the font resetting until after the reboot!

review: Approve
Revision history for this message
Nick Rosbrook (enr0n) wrote :

> This looks good to me now. Didn't know that the rpartition() method existed,
> but it fits well in this context. And it did The Right Thing for me when
> testing.
>
> Thanks for your work, and especially the idea to postpone the font resetting
> until after the reboot!

Glad it works well for you now. Thanks for all of your help on this!

Revision history for this message
Brian Murray (brian-murray) wrote :

This looks great to me, my only suggestion would be putting 'Sans' in a variable in case we change our minds some day.

review: Needs Fixing
Revision history for this message
Brian Murray (brian-murray) :
review: Approve
Revision history for this message
Nick Rosbrook (enr0n) wrote :

> This looks great to me, my only suggestion would be putting 'Sans' in a
> variable in case we change our minds some day.

Ack, will do before I merge. Thanks!

Revision history for this message
Gunnar Hjalmarsson (gunnarhj) wrote :

On 2023-09-29 17:18, Brian Murray wrote:
> ... in case we change our minds some day.

FTR I have anticipated that we may want to change our minds in next cycle:

https://git.launchpad.net/~ubuntu-core-dev/ubuntu-seeds/+git/platform/commit/?id=67c4e53c

i.e. for the case the fonts-noto source package gets updated with latest upstream.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/DistUpgrade/DistUpgradeController.py b/DistUpgrade/DistUpgradeController.py
2index 5e4e125..bb30eb2 100644
3--- a/DistUpgrade/DistUpgradeController.py
4+++ b/DistUpgrade/DistUpgradeController.py
5@@ -644,6 +644,15 @@ class DistUpgradeController(object):
6 ):
7 continue
8
9+ # subiquity was inadvertently configuring installed systems to use
10+ # $cc.archive.ubuntu.com as the mirror for the security pocket,
11+ # instead of security.ubuntu.com. (LP: #2036679)
12+ if (
13+ entry.dist == f'{self.fromDist}-security' and
14+ 'archive.ubuntu.com/ubuntu' in entry.uri
15+ ):
16+ entry.uri = self.security_source_uri
17+
18 new_list.append(entry)
19 self.sources.list = new_list
20
21diff --git a/DistUpgrade/DistUpgradeQuirks.py b/DistUpgrade/DistUpgradeQuirks.py
22index 0bd1ef9..0626694 100644
23--- a/DistUpgrade/DistUpgradeQuirks.py
24+++ b/DistUpgrade/DistUpgradeQuirks.py
25@@ -25,9 +25,11 @@ import distro_info
26 import glob
27 import logging
28 import os
29+import pwd
30 import re
31 import hashlib
32 import subprocess
33+import pathlib
34 from subprocess import PIPE, Popen
35
36 from .utils import get_arch
37@@ -55,6 +57,7 @@ class DistUpgradeQuirks(object):
38 self._snap_list = None
39 self._from_version = None
40 self._to_version = None
41+ self._did_change_font = False
42
43 # the quirk function have the name:
44 # $Name (e.g. PostUpgrade)
45@@ -168,6 +171,7 @@ class DistUpgradeQuirks(object):
46 self._killKBluetooth()
47 self._pokeScreensaver()
48 self._stopDocvertConverter()
49+ self._set_generic_font()
50
51 # individual quirks handler that run *right before* the dist-upgrade
52 # is calculated in the cache
53@@ -737,7 +741,9 @@ class DistUpgradeQuirks(object):
54 # _calculateSnapSizeRequirements call.
55 for snap, snap_object in self._snap_list.items():
56 command = snap_object['command']
57- if command == 'refresh':
58+ if command == 'switch':
59+ # TODO: This status should be updated, but the time of
60+ # this change to snap switch is post-translation freeze.
61 self._view.updateStatus(_("refreshing snap %s" % snap))
62 popenargs = ["snap", command,
63 "--channel", snap_object['channel'], snap]
64@@ -1194,13 +1200,13 @@ class DistUpgradeQuirks(object):
65 self._view.processEvents()
66 if re.search("^installed: ", snap_info[0], re.MULTILINE):
67 logging.debug("Snap %s is installed" % snap)
68- # its not tracking the release channel so don't refresh
69+ # its not tracking the release channel so don't switch
70 if not re.search(r"^tracking:.*%s" % from_channel,
71 snap_info[0], re.MULTILINE):
72 logging.debug("Snap %s is not tracking the release channel"
73 % snap)
74 continue
75- snap_object['command'] = 'refresh'
76+ snap_object['command'] = 'switch'
77 else:
78 # Do not replace packages not installed
79 cache = self.controller.cache
80@@ -1257,7 +1263,7 @@ class DistUpgradeQuirks(object):
81 logging.debug("Snap %s is being used by %s. "
82 "Switching it to stable track"
83 % (snap, plug_snap))
84- snap_object['command'] = 'refresh'
85+ snap_object['command'] = 'switch'
86 snap_object['channel'] = 'stable'
87 break
88
89@@ -1447,3 +1453,104 @@ class DistUpgradeQuirks(object):
90 except IOError as exc:
91 logging.error("unable to write new boot config to %s: %s; %s",
92 boot_config_filename, exc, failure_action)
93+
94+ def _set_generic_font(self):
95+ """ Due to changes to the Ubuntu font we enable a generic font
96+ (in practice DejaVu or Noto) during the upgrade.
97+ See https://launchpad.net/bugs/2034986
98+ """
99+ temp_font = 'Sans'
100+
101+ if self._did_change_font:
102+ return
103+
104+ try:
105+ uid = int(os.getenv('SUDO_UID', os.getenv('PKEXEC_UID')))
106+ pwuid = pwd.getpwuid(uid)
107+ except ValueError:
108+ logging.debug(
109+ 'Cannot determine non-root UID, will not change font'
110+ )
111+ return
112+
113+ r = subprocess.run(
114+ ['systemd-run', '--user', '-M', f'{pwuid.pw_name}@.host',
115+ '--wait', '--pipe', '-q', '--',
116+ '/usr/bin/gsettings', 'get',
117+ 'org.gnome.desktop.interface', 'font-name'],
118+ stdout=subprocess.PIPE,
119+ encoding='utf-8',
120+ )
121+
122+ (font, _, size) = r.stdout.strip('\'\n').rpartition(' ')
123+ font = font or 'Ubuntu'
124+ try:
125+ int(size)
126+ except ValueError:
127+ size = '11'
128+
129+ logging.debug(f'Setting generic font {temp_font} {size} during the '
130+ f'upgrade. Original font is {font} {size}.')
131+
132+ r = subprocess.run([
133+ 'systemd-run', '--user', '-M', f'{pwuid.pw_name}@.host',
134+ '--wait', '--pipe', '-q', '--',
135+ '/usr/bin/gsettings', 'set', 'org.gnome.desktop.interface',
136+ 'font-name', f'"{temp_font} {size}"'
137+ ])
138+ if r.returncode != 0:
139+ logging.debug(f'Failed to change font to {temp_font} {size}')
140+ return
141+
142+ self._did_change_font = True
143+
144+ # Touch a file to indiate that the font should be restored on the next
145+ # boot.
146+ need_font_restore_file = os.path.join(
147+ pwuid.pw_dir, '.config/upgrade-need-font-restore'
148+ )
149+ os.makedirs(os.path.dirname(need_font_restore_file), exist_ok=True)
150+ pathlib.Path(need_font_restore_file).touch(mode=0o666)
151+ os.chown(need_font_restore_file, pwuid.pw_uid, pwuid.pw_gid)
152+
153+ # If we set the font back to normal before a reboot, the font will
154+ # still get all messed up. To allow normal usage whether the user
155+ # reboots immediately or not, create a service that will run only if a
156+ # ~/.config/upgrade-need-font-restore exists, and then remove that file
157+ # in ExecStart. This has the effect of creating a one-time service on
158+ # the next boot.
159+ unit_file = '/usr/lib/systemd/user/upgrade-restore-font.service'
160+ os.makedirs(os.path.dirname(unit_file), exist_ok=True)
161+
162+ with open(unit_file, 'w') as f:
163+ f.write(
164+ '# Auto-generated by ubuntu-release-upgrader\n'
165+ '[Unit]\n'
166+ 'Description=Restore font after upgrade\n'
167+ 'After=graphical-session.target dconf.service\n'
168+ 'ConditionPathExists=%h/.config/upgrade-need-font-restore\n'
169+ '\n'
170+ '[Service]\n'
171+ 'Type=oneshot\n'
172+ 'ExecStart=/usr/bin/gsettings set '
173+ f'org.gnome.desktop.interface font-name \'{font} {size}\'\n'
174+ 'ExecStart=/usr/bin/rm -f '
175+ '%h/.config/upgrade-need-font-restore\n'
176+ '\n'
177+ '[Install]\n'
178+ 'WantedBy=graphical-session.target\n'
179+ )
180+
181+ subprocess.run([
182+ 'systemctl',
183+ '--user', '-M', f'{pwuid.pw_name}@.host',
184+ 'daemon-reload'
185+ ])
186+ r = subprocess.run([
187+ 'systemctl',
188+ '--user', '-M', f'{pwuid.pw_name}@.host',
189+ 'enable', os.path.basename(unit_file)
190+ ])
191+ if r.returncode != 0:
192+ logging.debug(f'Failed to enable {os.path.basename(unit_file)}. '
193+ 'Font will not be restored on reboot')
194diff --git a/DistUpgrade/DistUpgradeVersion.py b/DistUpgrade/DistUpgradeVersion.py
195index 71fb1a7..2b0dece 100644
196--- a/DistUpgrade/DistUpgradeVersion.py
197+++ b/DistUpgrade/DistUpgradeVersion.py
198@@ -1 +1 @@
199-VERSION = '23.10.6'
200+VERSION = '23.10.7'
201diff --git a/data/mirrors.cfg b/data/mirrors.cfg
202index 2c54596..59bebe7 100644
203--- a/data/mirrors.cfg
204+++ b/data/mirrors.cfg
205@@ -213,7 +213,6 @@ http://mirror.aminidc.com/ubuntu/
206 http://ubuntu.man.lodz.pl/ubuntu/
207 http://ubuntu.dts.mg/ubuntu/
208 http://ubuntu.mirror.true.nl/ubuntu/
209-http://mirror.wiru.co.za/ubuntu/
210 http://mirrors.up.pt/ubuntu/
211 http://www.club.cc.cmu.edu/pub/ubuntu/
212 http://archive.ubuntu.mirror.ba/ubuntu/
213@@ -278,7 +277,6 @@ http://ftp.belnet.be/ubuntu/
214 http://repo.miserver.it.umich.edu/ubuntu/
215 http://no.mirrors.blix.com/ubuntu/
216 http://ftp.jaist.ac.jp/pub/Linux/ubuntu/
217-http://mirrors.asnet.am/ubuntu/
218 http://mirrors.liquidweb.com/ubuntu/
219 http://mirrors.dotsrc.org/ubuntu/
220 http://mirrors.melbourne.co.uk/ubuntu/
221@@ -290,7 +288,6 @@ http://mirror.docker.ru/ubuntu/
222 http://mirror.pit.teraswitch.com/ubuntu/
223 http://mirrors.sohu.com/ubuntu/
224 http://mirror.metrocast.net/ubuntu/
225-http://reflector.westga.edu/repos/Ubuntu/archive/
226 http://hk.mirrors.thegigabit.com/ubuntu/
227 http://mirror.eu-fr.kamatera.com/ubuntu/
228 http://mirror.nwlab.tk/ubuntu/
229@@ -434,7 +431,6 @@ https://repo.extreme-ix.org/ubuntu/
230 https://mirror.coganng.com/ubuntu-ports/
231 https://mirror.bjtu.edu.cn/ubuntu/
232 https://ftp.tc.edu.tw/Linux/ubuntu/
233-https://mirror.onlinehosting.com.tr/ubuntu/
234 http://mirror.cepatcloud.id/ubuntu/
235 https://mirror.dkm.cz/ubuntu/
236 http://ossmirror.mycloud.services/os/linux/ubuntu/
237@@ -452,7 +448,6 @@ https://mirror.lyrahosting.com/ubuntuarchive/
238 https://ftp.sh.cvut.cz/ubuntu/
239 https://mirror.pulsant.com/sites/ubuntu-archive/
240 https://mirror.netcologne.de/ubuntu/
241-http://mirror.beon.co.id/ubuntu/
242 https://mirrors.nipa.cloud/ubuntu/
243 https://ubuntu.lafibre.info/ubuntu/
244 https://mirror.hostart.az/Ubuntu/
245@@ -492,7 +487,6 @@ https://mirrors.nav.ro/ubuntu/
246 https://mirror.webworld.ie/ubuntu/
247 https://mirror.scaleuptech.com/ubuntu/
248 https://mirrors.nxtgen.com/ubuntu-mirror/ubuntu/
249-http://mirror.soonkeat.sg/ubuntu/
250 https://it1.mirror.vhosting-it.com/ubuntu/
251 https://it2.mirror.vhosting-it.com/ubuntu/
252 https://ubuntu.hi.no/archive/
253@@ -564,7 +558,6 @@ https://mirror.servaxnet.com/ubuntu/
254 http://mirror.vietnix.vn/ubuntu/
255 https://ubuntu.hostiran.ir/ubuntuarchive/
256 http://repo.ugm.ac.id/ubuntu/
257-https://mirrors.zju.edu.cn/ubuntu/
258 http://mirror.espol.edu.ec/ubuntu/
259 http://ubuntu.mirror.iweb.ca/
260 https://labs.eif.urjc.es/mirror/ubuntu/
261@@ -575,9 +568,6 @@ http://mirror.timeweb.ru/ubuntu/
262 http://ubuntu.byteiran.com/ubuntu/
263 https://ubuntu.ccns.ncku.edu.tw/ubuntu/
264 https://mirror.repository.id/ubuntu/
265-https://mirror.papua.go.id/ubuntu/
266-https://mirror.faizuladib.com/ubuntu/
267-https://mirror.gi.co.id/ubuntu/
268 https://mirrors.jlu.edu.cn/ubuntu/
269 http://mirror.unesp.br/ubuntu/
270 http://ubuntu.org.ua/ubuntu/
271@@ -634,3 +624,11 @@ https://repo.jing.rocks/ubuntu/
272 https://mirror.citrahost.com/ubuntu/
273 https://mirror.siwoo.org/ubuntu/
274 https://mirror.gsl.icu/ubuntu/
275+http://linuxmirrors.ir/pub/ubuntu/
276+https://mirror.neftm.ru/ubuntu/
277+https://mirror.timkevin.us/ubuntu/
278+http://mirror.lzu.edu.cn/ubuntu/
279+https://ftp.kaist.ac.kr/ubuntu/
280+https://mirrors.xtom.de/ubuntu/
281+https://mirror.netzwerge.de/ubuntu/
282+https://mirrors.ocf.berkeley.edu/ubuntu-ports/
283diff --git a/debian/changelog b/debian/changelog
284index c97e3e8..6ee8764 100644
285--- a/debian/changelog
286+++ b/debian/changelog
287@@ -1,3 +1,15 @@
288+ubuntu-release-upgrader (1:23.10.7) mantic; urgency=medium
289+
290+ * DistUpgradeQuirks: Use generic font temporarily at upgrade
291+ (LP: #2034986)
292+ * DistUpgradeQuirks: Switch snap channels instead of refresh
293+ (LP: #2036765)
294+ * DistUpgradeController: Ensure security archive is used for security pocket
295+ (LP: #2036679)
296+ * Run pre-build.sh: updating mirrors and demotions.
297+
298+ -- Nick Rosbrook <enr0n@ubuntu.com> Fri, 29 Sep 2023 10:36:00 -0400
299+
300 ubuntu-release-upgrader (1:23.10.6) mantic; urgency=medium
301
302 * DistUpgrade: do not migrate to deb822 by default (LP: #2036288)
303diff --git a/utils/demoted.cfg b/utils/demoted.cfg
304index 4093061..fd3c64f 100644
305--- a/utils/demoted.cfg
306+++ b/utils/demoted.cfg
307@@ -43,9 +43,13 @@ libgcc-12-dev-s390x-cross
308 libgfortran-12-dev
309 libmlir-15
310 libmlir-15-dev
311+libpcre16-3
312+libpcre3
313+libpcre3-dbg
314+libpcre3-dev
315+libpcre32-3
316+libpcrecpp0v5
317 libpolly-15-dev
318-libpoppler126
319-libstd-rust-dev
320 libstdc++-12-dev
321 libstdc++-12-dev-arm64-cross
322 libstdc++-12-dev-armhf-cross
323@@ -65,7 +69,6 @@ python3-renderpm
324 python3-reportlab
325 python3-reportlab-accel
326 rhythmbox-dev
327-rustc
328 ubuntu-image
329 ubuntu-wallpapers-lunar
330 util-linux-extra
331diff --git a/utils/demoted.cfg.jammy b/utils/demoted.cfg.jammy
332index a66dd4c..a2c0175 100644
333--- a/utils/demoted.cfg.jammy
334+++ b/utils/demoted.cfg.jammy
335@@ -105,6 +105,12 @@ libmoox-struct-perl
336 libnamespace-autoclean-perl
337 libnet-ip-perl
338 libobject-id-perl
339+libpcre16-3
340+libpcre3
341+libpcre3-dbg
342+libpcre3-dev
343+libpcre32-3
344+libpcrecpp0v5
345 libpfm4
346 libpfm4-dev
347 libpulsedsp
348@@ -118,7 +124,6 @@ libsoxr-lsr0
349 libsoxr0
350 libspeexdsp-dev
351 libspeexdsp1
352-libstd-rust-dev
353 libstdc++-11-dev-arm64-cross
354 libstdc++-11-dev-armhf-cross
355 libstdc++-11-dev-ppc64el-cross
356@@ -173,6 +178,5 @@ python3-reportlab-accel
357 python3-rfc3339
358 python3-sphinx-rtd-theme
359 rhythmbox-dev
360-rustc
361 ubuntu-image
362 ubuntu-wallpapers-jammy

Subscribers

People subscribed via source and target branches