Merge ~waveform/ubuntu-release-upgrader:lp2065051-oracular into ubuntu-release-upgrader:ubuntu/main

Proposed by Dave Jones
Status: Merged
Merge reported by: Nick Rosbrook
Merged at revision: 5d8e7f4df956ae107cba343d5ebdeb638a7a2819
Proposed branch: ~waveform/ubuntu-release-upgrader:lp2065051-oracular
Merge into: ubuntu-release-upgrader:ubuntu/main
Diff against target: 261 lines (+179/-28)
3 files modified
DistUpgrade/DistUpgradeQuirks.py (+93/-28)
debian/changelog (+7/-0)
tests/test_quirks.py (+79/-0)
Reviewer Review Type Date Requested Status
Nick Rosbrook Approve
Review via email: mp+465724@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Nick Rosbrook (enr0n) wrote :

Looks good except that the test you added fails, but it looks trivial to fix. Note that I modified it locally to get the diff:

======================================================================
FAIL: test_add_kms_overlay_with_changes (test_quirks.TestQuirks.test_add_kms_overlay_with_changes)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/nr/ubuntu/code/ubuntu-release-upgrader/tests/test_quirks.py", line 603, in test_add_kms_overlay_with_changes
    self.assertEqual(f.read(), expected_config_txt)
AssertionError: 'arm_[55 chars]nel\n\ndtoverlay=vc4-kms-v3d\ndisable_fw_kms_s[122 chars]=2\n' != 'arm_[55 chars]nel\n# added by do-release-upgrade (LP: #20650[166 chars]=2\n'
  arm_64bit=1
  kernel=vmlinuz
  initramfs initrd.img followkernel
-
+ # added by do-release-upgrade (LP: #2065051)
  dtoverlay=vc4-kms-v3d
  disable_fw_kms_setup=1

  [pi3+]
  dtoverlay=vc4-kms-v3d,cma-128

  [pi02]
  dtoverlay=vc4-kms-v3d,cma-128

  [all]
  [pi4]
  max_framebuffers=2

----------------------------------------------------------------------

review: Needs Fixing
Revision history for this message
Dave Jones (waveform) wrote :

Urgh -- I ran the autopkgtest locally, but only fixed the noble branch and forgot the oracular one. Anyway, just force-pushed the branch to fix it.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/DistUpgrade/DistUpgradeQuirks.py b/DistUpgrade/DistUpgradeQuirks.py
2index a50ce8a..cb7190f 100644
3--- a/DistUpgrade/DistUpgradeQuirks.py
4+++ b/DistUpgrade/DistUpgradeQuirks.py
5@@ -156,6 +156,9 @@ class DistUpgradeQuirks(object):
6 if 'ubuntu-desktop-raspi' in cache:
7 if cache['ubuntu-desktop-raspi'].is_installed:
8 self._replace_fkms_overlay()
9+ if 'ubuntu-server-raspi' in cache:
10+ if cache['ubuntu-server-raspi'].is_installed:
11+ self._add_kms_overlay()
12 if 'linux-firmware-raspi2' in cache:
13 if cache['linux-firmware-raspi2'].is_installed:
14 self._remove_uboot_on_rpi()
15@@ -1284,6 +1287,23 @@ class DistUpgradeQuirks(object):
16 self._snap_list[snap] = snap_object
17 return self._snap_list
18
19+ def _replace_pi_boot_config(self, old_config, new_config,
20+ boot_config_filename, failure_action):
21+ try:
22+ boot_backup_filename = boot_config_filename + '.distUpgrade'
23+ with open(boot_backup_filename, 'w', encoding='utf-8') as f:
24+ f.write(old_config)
25+ except IOError as exc:
26+ logging.error("unable to write boot config backup to %s: %s; %s",
27+ boot_backup_filename, exc, failure_action)
28+ return
29+ try:
30+ with open(boot_config_filename, 'w', encoding='utf-8') as f:
31+ f.write(new_config)
32+ except IOError as exc:
33+ logging.error("unable to write new boot config to %s: %s; %s",
34+ boot_config_filename, exc, failure_action)
35+
36 def _replace_fkms_overlay(self, boot_dir='/boot/firmware'):
37 failure_action = (
38 "You may need to replace the vc4-fkms-v3d overlay with "
39@@ -1318,22 +1338,80 @@ class DistUpgradeQuirks(object):
40 logging.warning("no fkms overlay or camera firmware line found "
41 "in %s", boot_config_filename)
42 return
43+ self._replace_pi_boot_config(
44+ boot_config, new_config, boot_config_filename, failure_action)
45
46+ def _add_kms_overlay(self, boot_dir='/boot/firmware'):
47+ failure_action = (
48+ "You may need to add dtoverlay=vc4-kms-v3d to an [all] section "
49+ "in config.txt on your boot partition")
50+ added_lines = [
51+ '# added by do-release-upgrade (LP: #2065051)',
52+ 'dtoverlay=vc4-kms-v3d',
53+ 'disable_fw_kms_setup=1',
54+ '',
55+ '[pi3+]',
56+ 'dtoverlay=vc4-kms-v3d,cma-128',
57+ '',
58+ '[pi02]',
59+ 'dtoverlay=vc4-kms-v3d,cma-128',
60+ '',
61+ '[all]',
62+ ]
63 try:
64- boot_backup_filename = os.path.join(
65- boot_dir, 'config.txt.distUpgrade')
66- with open(boot_backup_filename, 'w', encoding='utf-8') as f:
67- f.write(boot_config)
68- except IOError as exc:
69- logging.error("unable to write boot config backup to %s: %s; %s",
70- boot_backup_filename, exc, failure_action)
71+ boot_config_filename = os.path.join(boot_dir, 'config.txt')
72+ with open(boot_config_filename, 'r', encoding='utf-8') as f:
73+ boot_config = f.read()
74+ except FileNotFoundError:
75+ logging.error("failed to open boot configuration in %s; %s",
76+ boot_config_filename, failure_action)
77 return
78- try:
79- with open(boot_config_filename, 'w', encoding='utf-8') as f:
80- f.write(new_config)
81- except IOError as exc:
82- logging.error("unable to write new boot config to %s: %s; %s",
83- boot_config_filename, exc, failure_action)
84+
85+ def find_insertion_point(lines):
86+ # Returns the zero-based index of the dtoverlay=vc4-kms-v3d line in
87+ # an [all] section, if one exists, or the last line of the last
88+ # [all] section of the file, if one does not exist
89+ in_all = True
90+ last = 0
91+ for index, line in enumerate(lines):
92+ line = line.rstrip()
93+ if in_all:
94+ last = index
95+ # startswith used to cope with any trailing dtparams
96+ if line.startswith('dtoverlay=vc4-kms-v3d'):
97+ return last
98+ elif line.startswith('[') and line.endswith(']'):
99+ in_all = line == '[all]'
100+ elif line.startswith('include '):
101+ # [sections] are included from includes verbatim, hence
102+ # (without reading the included file) we must assume
103+ # we're no longer in an [all] section
104+ in_all = False
105+ else:
106+ in_all = line == '[all]'
107+ return last
108+
109+ def add_kms_overlay(lines):
110+ insert_point = find_insertion_point(lines)
111+ try:
112+ if lines[insert_point].startswith('dtoverlay=vc4-kms-v3d'):
113+ return lines
114+ except IndexError:
115+ # Empty config, apparently!
116+ pass
117+ lines[insert_point:insert_point] = added_lines
118+ return lines
119+
120+ lines = [line.rstrip() for line in boot_config.splitlines()]
121+ lines = add_kms_overlay(lines)
122+ new_config = ''.join(line + '\n' for line in lines)
123+
124+ if new_config == boot_config:
125+ logging.warning("no addition of KMS overlay required in %s",
126+ boot_config_filename)
127+ return
128+ self._replace_pi_boot_config(
129+ boot_config, new_config, boot_config_filename, failure_action)
130
131 def _remove_uboot_on_rpi(self, boot_dir='/boot/firmware'):
132 kernel_line = 'kernel=vmlinuz'
133@@ -1452,21 +1530,8 @@ class DistUpgradeQuirks(object):
134 logging.warning("no u-boot removal performed in %s",
135 boot_config_filename)
136 return
137-
138- try:
139- boot_backup_filename = boot_config_filename + '.distUpgrade'
140- with open(boot_backup_filename, 'w', encoding='utf-8') as f:
141- f.write(boot_config)
142- except IOError as exc:
143- logging.error("unable to write boot config backup to %s: %s; %s",
144- boot_backup_filename, exc, failure_action)
145- return
146- try:
147- with open(boot_config_filename, 'w', encoding='utf-8') as f:
148- f.write(new_config)
149- except IOError as exc:
150- logging.error("unable to write new boot config to %s: %s; %s",
151- boot_config_filename, exc, failure_action)
152+ self._replace_pi_boot_config(
153+ boot_config, new_config, boot_config_filename, failure_action)
154
155 def _set_generic_font(self):
156 """ Due to changes to the Ubuntu font we enable a generic font
157diff --git a/debian/changelog b/debian/changelog
158index c6969ee..e68d2cd 100644
159--- a/debian/changelog
160+++ b/debian/changelog
161@@ -1,3 +1,10 @@
162+ubuntu-release-upgrader (1:24.10.3) UNRELEASED; urgency=medium
163+
164+ * DistUpgradeQuirks: add quirk to migrate Pi server users to the KMS
165+ overlay (LP: #2065051)
166+
167+ -- Dave Jones <dave.jones@canonical.com> Tue, 07 May 2024 21:57:12 +0100
168+
169 ubuntu-release-upgrader (1:24.10.2) oracular; urgency=medium
170
171 * data/release-upgrades: set Prompt=normal for oracular
172diff --git a/tests/test_quirks.py b/tests/test_quirks.py
173index f40d502..a3fabec 100644
174--- a/tests/test_quirks.py
175+++ b/tests/test_quirks.py
176@@ -522,6 +522,85 @@ dtoverlay=vc4-kms-v3d,cma-256
177 with open(os.path.join(boot_dir, 'config.txt')) as f:
178 self.assertTrue(f.read() == expected_config)
179
180+ def test_add_kms_overlay_no_config(self):
181+ with tempfile.TemporaryDirectory() as boot_dir:
182+ mock_controller = mock.Mock()
183+
184+ q = DistUpgradeQuirks(mock_controller, mock.Mock())
185+
186+ q._add_kms_overlay(boot_dir)
187+ self.assertFalse(os.path.exists(os.path.join(
188+ boot_dir, 'config.txt.distUpgrade')))
189+
190+ def test_add_kms_overlay_no_changes(self):
191+ with tempfile.TemporaryDirectory() as boot_dir:
192+ boot_config = """\
193+arm_64bit=1
194+kernel=vmlinuz
195+initramfs initrd.img followkernel
196+
197+# This line is implicitly in an [all] section and
198+# should prevent the quirk from doing anything
199+dtoverlay=vc4-kms-v3d,cma-128
200+
201+[pi4]
202+max_framebuffers=2
203+"""
204+ with open(os.path.join(boot_dir, 'config.txt'), 'w') as f:
205+ f.write(boot_config)
206+
207+ mock_controller = mock.Mock()
208+ q = DistUpgradeQuirks(mock_controller, mock.Mock())
209+ q._add_kms_overlay(boot_dir)
210+
211+ self.assertFalse(os.path.exists(os.path.join(
212+ boot_dir, 'config.txt.distUpgrade')))
213+ with open(os.path.join(boot_dir, 'config.txt')) as f:
214+ self.assertTrue(f.read() == boot_config)
215+
216+ def test_add_kms_overlay_with_changes(self):
217+ with tempfile.TemporaryDirectory() as boot_dir:
218+ config_txt = """\
219+arm_64bit=1
220+kernel=vmlinuz
221+initramfs initrd.img followkernel
222+
223+[pi4]
224+max_framebuffers=2
225+"""
226+ expected_config_txt = """\
227+arm_64bit=1
228+kernel=vmlinuz
229+initramfs initrd.img followkernel
230+
231+# added by do-release-upgrade (LP: #2065051)
232+dtoverlay=vc4-kms-v3d
233+disable_fw_kms_setup=1
234+
235+[pi3+]
236+dtoverlay=vc4-kms-v3d,cma-128
237+
238+[pi02]
239+dtoverlay=vc4-kms-v3d,cma-128
240+
241+[all]
242+[pi4]
243+max_framebuffers=2
244+"""
245+ with open(os.path.join(boot_dir, 'config.txt'), 'w') as f:
246+ f.write(config_txt)
247+
248+ mock_controller = mock.Mock()
249+ q = DistUpgradeQuirks(mock_controller, mock.Mock())
250+ q._add_kms_overlay(boot_dir)
251+
252+ self.assertTrue(os.path.exists(os.path.join(
253+ boot_dir, 'config.txt.distUpgrade')))
254+ self.assertTrue(os.path.exists(os.path.join(
255+ boot_dir, 'config.txt')))
256+ with open(os.path.join(boot_dir, 'config.txt')) as f:
257+ self.assertTrue(f.read() == expected_config_txt)
258+
259 def test_remove_uboot_no_config(self):
260 with tempfile.TemporaryDirectory() as boot_dir:
261 mock_controller = mock.Mock()

Subscribers

People subscribed via source and target branches