Merge ~waveform/ubuntu-release-upgrader:lp2065051-noble into ubuntu-release-upgrader:ubuntu/noble

Proposed by Dave Jones
Status: Merged
Merge reported by: Nick Rosbrook
Merged at revision: 86ae724556643768d0f68a08feedbefb867d18ee
Proposed branch: ~waveform/ubuntu-release-upgrader:lp2065051-noble
Merge into: ubuntu-release-upgrader:ubuntu/noble
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+465725@code.launchpad.net
To post a comment you must log in.
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
diff --git a/DistUpgrade/DistUpgradeQuirks.py b/DistUpgrade/DistUpgradeQuirks.py
index d3a0bbd..292394b 100644
--- a/DistUpgrade/DistUpgradeQuirks.py
+++ b/DistUpgrade/DistUpgradeQuirks.py
@@ -156,6 +156,9 @@ class DistUpgradeQuirks(object):
156 if 'ubuntu-desktop-raspi' in cache:156 if 'ubuntu-desktop-raspi' in cache:
157 if cache['ubuntu-desktop-raspi'].is_installed:157 if cache['ubuntu-desktop-raspi'].is_installed:
158 self._replace_fkms_overlay()158 self._replace_fkms_overlay()
159 if 'ubuntu-server-raspi' in cache:
160 if cache['ubuntu-server-raspi'].is_installed:
161 self._add_kms_overlay()
159 if 'linux-firmware-raspi2' in cache:162 if 'linux-firmware-raspi2' in cache:
160 if cache['linux-firmware-raspi2'].is_installed:163 if cache['linux-firmware-raspi2'].is_installed:
161 self._remove_uboot_on_rpi()164 self._remove_uboot_on_rpi()
@@ -1284,6 +1287,23 @@ class DistUpgradeQuirks(object):
1284 self._snap_list[snap] = snap_object1287 self._snap_list[snap] = snap_object
1285 return self._snap_list1288 return self._snap_list
12861289
1290 def _replace_pi_boot_config(self, old_config, new_config,
1291 boot_config_filename, failure_action):
1292 try:
1293 boot_backup_filename = boot_config_filename + '.distUpgrade'
1294 with open(boot_backup_filename, 'w', encoding='utf-8') as f:
1295 f.write(old_config)
1296 except IOError as exc:
1297 logging.error("unable to write boot config backup to %s: %s; %s",
1298 boot_backup_filename, exc, failure_action)
1299 return
1300 try:
1301 with open(boot_config_filename, 'w', encoding='utf-8') as f:
1302 f.write(new_config)
1303 except IOError as exc:
1304 logging.error("unable to write new boot config to %s: %s; %s",
1305 boot_config_filename, exc, failure_action)
1306
1287 def _replace_fkms_overlay(self, boot_dir='/boot/firmware'):1307 def _replace_fkms_overlay(self, boot_dir='/boot/firmware'):
1288 failure_action = (1308 failure_action = (
1289 "You may need to replace the vc4-fkms-v3d overlay with "1309 "You may need to replace the vc4-fkms-v3d overlay with "
@@ -1318,22 +1338,80 @@ class DistUpgradeQuirks(object):
1318 logging.warning("no fkms overlay or camera firmware line found "1338 logging.warning("no fkms overlay or camera firmware line found "
1319 "in %s", boot_config_filename)1339 "in %s", boot_config_filename)
1320 return1340 return
1341 self._replace_pi_boot_config(
1342 boot_config, new_config, boot_config_filename, failure_action)
13211343
1344 def _add_kms_overlay(self, boot_dir='/boot/firmware'):
1345 failure_action = (
1346 "You may need to add dtoverlay=vc4-kms-v3d to an [all] section "
1347 "in config.txt on your boot partition")
1348 added_lines = [
1349 '# added by do-release-upgrade (LP: #2065051)',
1350 'dtoverlay=vc4-kms-v3d',
1351 'disable_fw_kms_setup=1',
1352 '',
1353 '[pi3+]',
1354 'dtoverlay=vc4-kms-v3d,cma-128',
1355 '',
1356 '[pi02]',
1357 'dtoverlay=vc4-kms-v3d,cma-128',
1358 '',
1359 '[all]',
1360 ]
1322 try:1361 try:
1323 boot_backup_filename = os.path.join(1362 boot_config_filename = os.path.join(boot_dir, 'config.txt')
1324 boot_dir, 'config.txt.distUpgrade')1363 with open(boot_config_filename, 'r', encoding='utf-8') as f:
1325 with open(boot_backup_filename, 'w', encoding='utf-8') as f:1364 boot_config = f.read()
1326 f.write(boot_config)1365 except FileNotFoundError:
1327 except IOError as exc:1366 logging.error("failed to open boot configuration in %s; %s",
1328 logging.error("unable to write boot config backup to %s: %s; %s",1367 boot_config_filename, failure_action)
1329 boot_backup_filename, exc, failure_action)
1330 return1368 return
1331 try:1369
1332 with open(boot_config_filename, 'w', encoding='utf-8') as f:1370 def find_insertion_point(lines):
1333 f.write(new_config)1371 # Returns the zero-based index of the dtoverlay=vc4-kms-v3d line in
1334 except IOError as exc:1372 # an [all] section, if one exists, or the last line of the last
1335 logging.error("unable to write new boot config to %s: %s; %s",1373 # [all] section of the file, if one does not exist
1336 boot_config_filename, exc, failure_action)1374 in_all = True
1375 last = 0
1376 for index, line in enumerate(lines):
1377 line = line.rstrip()
1378 if in_all:
1379 last = index
1380 # startswith used to cope with any trailing dtparams
1381 if line.startswith('dtoverlay=vc4-kms-v3d'):
1382 return last
1383 elif line.startswith('[') and line.endswith(']'):
1384 in_all = line == '[all]'
1385 elif line.startswith('include '):
1386 # [sections] are included from includes verbatim, hence
1387 # (without reading the included file) we must assume
1388 # we're no longer in an [all] section
1389 in_all = False
1390 else:
1391 in_all = line == '[all]'
1392 return last
1393
1394 def add_kms_overlay(lines):
1395 insert_point = find_insertion_point(lines)
1396 try:
1397 if lines[insert_point].startswith('dtoverlay=vc4-kms-v3d'):
1398 return lines
1399 except IndexError:
1400 # Empty config, apparently!
1401 pass
1402 lines[insert_point:insert_point] = added_lines
1403 return lines
1404
1405 lines = [line.rstrip() for line in boot_config.splitlines()]
1406 lines = add_kms_overlay(lines)
1407 new_config = ''.join(line + '\n' for line in lines)
1408
1409 if new_config == boot_config:
1410 logging.warning("no addition of KMS overlay required in %s",
1411 boot_config_filename)
1412 return
1413 self._replace_pi_boot_config(
1414 boot_config, new_config, boot_config_filename, failure_action)
13371415
1338 def _remove_uboot_on_rpi(self, boot_dir='/boot/firmware'):1416 def _remove_uboot_on_rpi(self, boot_dir='/boot/firmware'):
1339 kernel_line = 'kernel=vmlinuz'1417 kernel_line = 'kernel=vmlinuz'
@@ -1452,21 +1530,8 @@ class DistUpgradeQuirks(object):
1452 logging.warning("no u-boot removal performed in %s",1530 logging.warning("no u-boot removal performed in %s",
1453 boot_config_filename)1531 boot_config_filename)
1454 return1532 return
14551533 self._replace_pi_boot_config(
1456 try:1534 boot_config, new_config, boot_config_filename, failure_action)
1457 boot_backup_filename = boot_config_filename + '.distUpgrade'
1458 with open(boot_backup_filename, 'w', encoding='utf-8') as f:
1459 f.write(boot_config)
1460 except IOError as exc:
1461 logging.error("unable to write boot config backup to %s: %s; %s",
1462 boot_backup_filename, exc, failure_action)
1463 return
1464 try:
1465 with open(boot_config_filename, 'w', encoding='utf-8') as f:
1466 f.write(new_config)
1467 except IOError as exc:
1468 logging.error("unable to write new boot config to %s: %s; %s",
1469 boot_config_filename, exc, failure_action)
14701535
1471 def _set_generic_font(self):1536 def _set_generic_font(self):
1472 """ Due to changes to the Ubuntu font we enable a generic font1537 """ Due to changes to the Ubuntu font we enable a generic font
diff --git a/debian/changelog b/debian/changelog
index 862afb2..825a2d7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
1ubuntu-release-upgrader (1:24.04.18) noble; urgency=medium
2
3 * DistUpgradeQuirks: add quirk to migrate Pi server users to the KMS
4 overlay (LP: #2065051)
5
6 -- Dave Jones <dave.jones@canonical.com> Tue, 07 May 2024 18:54:12 +0100
7
1ubuntu-release-upgrader (1:24.04.17) noble; urgency=medium8ubuntu-release-upgrader (1:24.04.17) noble; urgency=medium
29
3 [ Nick Rosbrook ]10 [ Nick Rosbrook ]
diff --git a/tests/test_quirks.py b/tests/test_quirks.py
index f40d502..a3fabec 100644
--- a/tests/test_quirks.py
+++ b/tests/test_quirks.py
@@ -522,6 +522,85 @@ dtoverlay=vc4-kms-v3d,cma-256
522 with open(os.path.join(boot_dir, 'config.txt')) as f:522 with open(os.path.join(boot_dir, 'config.txt')) as f:
523 self.assertTrue(f.read() == expected_config)523 self.assertTrue(f.read() == expected_config)
524524
525 def test_add_kms_overlay_no_config(self):
526 with tempfile.TemporaryDirectory() as boot_dir:
527 mock_controller = mock.Mock()
528
529 q = DistUpgradeQuirks(mock_controller, mock.Mock())
530
531 q._add_kms_overlay(boot_dir)
532 self.assertFalse(os.path.exists(os.path.join(
533 boot_dir, 'config.txt.distUpgrade')))
534
535 def test_add_kms_overlay_no_changes(self):
536 with tempfile.TemporaryDirectory() as boot_dir:
537 boot_config = """\
538arm_64bit=1
539kernel=vmlinuz
540initramfs initrd.img followkernel
541
542# This line is implicitly in an [all] section and
543# should prevent the quirk from doing anything
544dtoverlay=vc4-kms-v3d,cma-128
545
546[pi4]
547max_framebuffers=2
548"""
549 with open(os.path.join(boot_dir, 'config.txt'), 'w') as f:
550 f.write(boot_config)
551
552 mock_controller = mock.Mock()
553 q = DistUpgradeQuirks(mock_controller, mock.Mock())
554 q._add_kms_overlay(boot_dir)
555
556 self.assertFalse(os.path.exists(os.path.join(
557 boot_dir, 'config.txt.distUpgrade')))
558 with open(os.path.join(boot_dir, 'config.txt')) as f:
559 self.assertTrue(f.read() == boot_config)
560
561 def test_add_kms_overlay_with_changes(self):
562 with tempfile.TemporaryDirectory() as boot_dir:
563 config_txt = """\
564arm_64bit=1
565kernel=vmlinuz
566initramfs initrd.img followkernel
567
568[pi4]
569max_framebuffers=2
570"""
571 expected_config_txt = """\
572arm_64bit=1
573kernel=vmlinuz
574initramfs initrd.img followkernel
575
576# added by do-release-upgrade (LP: #2065051)
577dtoverlay=vc4-kms-v3d
578disable_fw_kms_setup=1
579
580[pi3+]
581dtoverlay=vc4-kms-v3d,cma-128
582
583[pi02]
584dtoverlay=vc4-kms-v3d,cma-128
585
586[all]
587[pi4]
588max_framebuffers=2
589"""
590 with open(os.path.join(boot_dir, 'config.txt'), 'w') as f:
591 f.write(config_txt)
592
593 mock_controller = mock.Mock()
594 q = DistUpgradeQuirks(mock_controller, mock.Mock())
595 q._add_kms_overlay(boot_dir)
596
597 self.assertTrue(os.path.exists(os.path.join(
598 boot_dir, 'config.txt.distUpgrade')))
599 self.assertTrue(os.path.exists(os.path.join(
600 boot_dir, 'config.txt')))
601 with open(os.path.join(boot_dir, 'config.txt')) as f:
602 self.assertTrue(f.read() == expected_config_txt)
603
525 def test_remove_uboot_no_config(self):604 def test_remove_uboot_no_config(self):
526 with tempfile.TemporaryDirectory() as boot_dir:605 with tempfile.TemporaryDirectory() as boot_dir:
527 mock_controller = mock.Mock()606 mock_controller = mock.Mock()

Subscribers

People subscribed via source and target branches