Note: I didn't actually test this on rawhide, I wrote it on master and backported it to rhel7-branch and tested there due to not having a rawhide dev env handy. If someone does, testing it will be a pain as you'll also need the newer rpm-ostree patch, and to compose a new tree with it and the ostree patch, etc.
From cc8aaa04f9e78916efd4b0cc2dae5507e176f591 Mon Sep 17 00:00:00 2001
From: Colin Walters walters@verbum.org Date: Mon, 13 Oct 2014 21:01:23 -0400 Subject: [PATCH] Handle the case of rpmostreepayload + GRUB2
NOTE: Incompatible change for trees constructed prior to NOTE: https://github.com/projectatomic/rpm-ostree/pull/35
For rpmostreepayload (in contrast to yum mainline) is that Anaconda lays down the bootloader data and computes the kernel arguments, but ostree takes care of writing the configuration file (as it does on upgrades as well).
However, the handling of /boot in OSTree was a bit broken, and trying to support GRUB2 forced this change, because we need to ultimately execute grub2-mkconfig in the chroot and we need both the *real* /boot as well as the new /usr/lib/ostree-boot.
We switch to keeping /boot in the target root, and call ostree from there. This should still work for extlinux because we're just rewriting a config file.
For moving the GRUB2 config file, see a similar change for rpmostreepayload+extlinux in commit: 627486c22cdaf6c07009026791f5bd6fc1aaadaa
Note: This commit is only useful on BIOS systems as of yet. --- pyanaconda/bootloader.py | 9 +++++---- pyanaconda/install.py | 17 ----------------- pyanaconda/packaging/rpmostreepayload.py | 22 ++++++++++++++++++---- 3 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py index b021067..8cdbd2f 100644 --- a/pyanaconda/bootloader.py +++ b/pyanaconda/bootloader.py @@ -1547,10 +1547,11 @@ class GRUB2(GRUB): log.error("boot loader password setup failed: %s", e)
# make sure the default entry is the OS we are installing - entry_title = "0" - rc = iutil.execInSysroot("grub2-set-default", [entry_title]) - if rc: - log.error("failed to set default menu entry to %s", productName) + if self.default is not None: + entry_title = "0" + rc = iutil.execInSysroot("grub2-set-default", [entry_title]) + if rc: + log.error("failed to set default menu entry to %s", productName)
# now tell grub2 to generate the main configuration file rc = iutil.execInSysroot("grub2-mkconfig", diff --git a/pyanaconda/install.py b/pyanaconda/install.py index 40ead97..94f4663 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -118,20 +118,6 @@ def doConfiguration(storage, payload, ksdata, instClass):
progress_complete()
-def moveBootMntToPhysical(storage): - """Move the /boot mount to /mnt/sysimage/boot.""" - if iutil.getSysroot() == iutil.getTargetPhysicalRoot(): - return - - mounts = [storage.mountpoints.get("/boot/efi"), storage.mountpoints.get("/boot")] - for mnt in mounts: - if mnt is None: - return - - mnt.format.teardown() - mnt.teardown() - mnt.format.setup(options=mnt.format.options, chroot=iutil.getTargetPhysicalRoot()) - def doInstall(storage, payload, ksdata, instClass): """Perform an installation. This method takes the ksdata as prepared by the UI (the first hub, in graphical mode) and applies it to the disk. @@ -266,9 +252,6 @@ def doInstall(storage, payload, ksdata, instClass): writeBootLoader(storage, payload, instClass, ksdata)
with progress_report(_("Performing post-installation setup tasks")): - # Now, let's reset the state here so that the payload has - # /boot in the system root. - moveBootMntToPhysical(storage) payload.postInstall()
progress_complete() diff --git a/pyanaconda/packaging/rpmostreepayload.py b/pyanaconda/packaging/rpmostreepayload.py index 70a4903..8d3ff42 100644 --- a/pyanaconda/packaging/rpmostreepayload.py +++ b/pyanaconda/packaging/rpmostreepayload.py @@ -219,7 +219,8 @@ class RPMOSTreePayload(ArchivePayload): def postInstall(self): super(RPMOSTreePayload, self).postInstall()
- physboot = iutil.getTargetPhysicalRoot() + '/boot' + # not actually "phys" anymore, not changed to avoid diff spam + physboot = iutil.getSysroot() + '/boot'
# If we're using extlinux, rename extlinux.conf to # syslinux.cfg, since that's what OSTree knows about. @@ -240,11 +241,24 @@ class RPMOSTreePayload(ArchivePayload): # And *also* tell syslinux that the config is really in /boot/loader os.symlink('loader/syslinux.cfg', physboot + '/syslinux.cfg')
+ # And if we're using GRUB2, move its config file, also with a + # compatibility symlink. + physboot_grub2 = physboot + '/grub2' + if os.path.isdir(physboot_grub2): + physboot_loader = physboot + '/loader' + assert os.path.isdir(physboot_loader) + orig_grub_cfg = physboot_grub2 + '/grub.cfg' + target_grub_cfg = physboot_loader + '/grub.cfg' + log.info("Moving %s -> %s", orig_grub_cfg, target_grub_cfg) + os.rename(orig_grub_cfg, target_grub_cfg) + os.symlink('../loader/grub.cfg', orig_grub_cfg) + # OSTree owns the bootloader configuration, so here we give it # the argument list we computed from storage, architecture and # such. - set_kargs_args = ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), - "instutil", "set-kargs"] + set_kargs_args = ["admin", "instutil", "set-kargs"] set_kargs_args.extend(self.storage.bootloader.boot_args) set_kargs_args.append("root=" + self.storage.rootDevice.fstabSpec) - self._safeExecWithRedirect("ostree", set_kargs_args) + # Here we run ostree from the target system, because the bootloader + # code for GRUB2 needs to run grub2-mkconfig. + self._safeExecWithRedirect("ostree", set_kargs_args, root=iutil.getSysroot())
Looks OK to me, I don't see anything that would break things. I would rename the physboot though.
On 10/16/2014 04:23 AM, Colin Walters wrote:
Note: I didn't actually test this on rawhide, I wrote it on master and backported it to rhel7-branch and tested there due to not having a rawhide dev env handy. If someone does, testing it will be a pain as you'll also need the newer rpm-ostree patch, and to compose a new tree with it and the ostree patch, etc.
From cc8aaa04f9e78916efd4b0cc2dae5507e176f591 Mon Sep 17 00:00:00 2001 From: Colin Walters walters@verbum.org Date: Mon, 13 Oct 2014 21:01:23 -0400 Subject: [PATCH] Handle the case of rpmostreepayload + GRUB2
NOTE: Incompatible change for trees constructed prior to NOTE: https://github.com/projectatomic/rpm-ostree/pull/35
For rpmostreepayload (in contrast to yum mainline) is that Anaconda lays down the bootloader data and computes the kernel arguments, but ostree takes care of writing the configuration file (as it does on upgrades as well).
However, the handling of /boot in OSTree was a bit broken, and trying to support GRUB2 forced this change, because we need to ultimately execute grub2-mkconfig in the chroot and we need both the *real* /boot as well as the new /usr/lib/ostree-boot.
We switch to keeping /boot in the target root, and call ostree from there. This should still work for extlinux because we're just rewriting a config file.
For moving the GRUB2 config file, see a similar change for rpmostreepayload+extlinux in commit: 627486c22cdaf6c07009026791f5bd6fc1aaadaa
Note: This commit is only useful on BIOS systems as of yet.
pyanaconda/bootloader.py | 9 +++++---- pyanaconda/install.py | 17 ----------------- pyanaconda/packaging/rpmostreepayload.py | 22 ++++++++++++++++++---- 3 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py index b021067..8cdbd2f 100644 --- a/pyanaconda/bootloader.py +++ b/pyanaconda/bootloader.py @@ -1547,10 +1547,11 @@ class GRUB2(GRUB): log.error("boot loader password setup failed: %s", e)
# make sure the default entry is the OS we are installing
entry_title = "0"
rc = iutil.execInSysroot("grub2-set-default", [entry_title])
if rc:
log.error("failed to set default menu entry to %s",
productName)
if self.default is not None:
entry_title = "0"
rc = iutil.execInSysroot("grub2-set-default",
[entry_title])
if rc:
log.error("failed to set default menu entry to %s",
productName)
# now tell grub2 to generate the main configuration file rc = iutil.execInSysroot("grub2-mkconfig",
diff --git a/pyanaconda/install.py b/pyanaconda/install.py index 40ead97..94f4663 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -118,20 +118,6 @@ def doConfiguration(storage, payload, ksdata, instClass):
progress_complete()
-def moveBootMntToPhysical(storage):
- """Move the /boot mount to /mnt/sysimage/boot."""
- if iutil.getSysroot() == iutil.getTargetPhysicalRoot():
return
- mounts = [storage.mountpoints.get("/boot/efi"),
storage.mountpoints.get("/boot")]
- for mnt in mounts:
if mnt is None:
return
mnt.format.teardown()
mnt.teardown()
mnt.format.setup(options=mnt.format.options,
chroot=iutil.getTargetPhysicalRoot())
- def doInstall(storage, payload, ksdata, instClass): """Perform an installation. This method takes the ksdata as prepared by the UI (the first hub, in graphical mode) and applies it to the disk.
@@ -266,9 +252,6 @@ def doInstall(storage, payload, ksdata, instClass): writeBootLoader(storage, payload, instClass, ksdata)
with progress_report(_("Performing post-installation setup tasks")):
# Now, let's reset the state here so that the payload has
# /boot in the system root.
moveBootMntToPhysical(storage) payload.postInstall() progress_complete()
diff --git a/pyanaconda/packaging/rpmostreepayload.py b/pyanaconda/packaging/rpmostreepayload.py index 70a4903..8d3ff42 100644 --- a/pyanaconda/packaging/rpmostreepayload.py +++ b/pyanaconda/packaging/rpmostreepayload.py @@ -219,7 +219,8 @@ class RPMOSTreePayload(ArchivePayload): def postInstall(self): super(RPMOSTreePayload, self).postInstall()
physboot = iutil.getTargetPhysicalRoot() + '/boot'
# not actually "phys" anymore, not changed to avoid diff spam
physboot = iutil.getSysroot() + '/boot' # If we're using extlinux, rename extlinux.conf to # syslinux.cfg, since that's what OSTree knows about.
@@ -240,11 +241,24 @@ class RPMOSTreePayload(ArchivePayload): # And *also* tell syslinux that the config is really in /boot/loader os.symlink('loader/syslinux.cfg', physboot + '/syslinux.cfg')
# And if we're using GRUB2, move its config file, also with a
# compatibility symlink.
physboot_grub2 = physboot + '/grub2'
if os.path.isdir(physboot_grub2):
physboot_loader = physboot + '/loader'
assert os.path.isdir(physboot_loader)
orig_grub_cfg = physboot_grub2 + '/grub.cfg'
target_grub_cfg = physboot_loader + '/grub.cfg'
log.info("Moving %s -> %s", orig_grub_cfg, target_grub_cfg)
os.rename(orig_grub_cfg, target_grub_cfg)
os.symlink('../loader/grub.cfg', orig_grub_cfg)
# OSTree owns the bootloader configuration, so here we give it # the argument list we computed from storage, architecture and # such.
set_kargs_args = ["admin", "--sysroot=" +
iutil.getTargetPhysicalRoot(),
"instutil", "set-kargs"]
set_kargs_args = ["admin", "instutil", "set-kargs"] set_kargs_args.extend(self.storage.bootloader.boot_args) set_kargs_args.append("root=" + self.storage.rootDevice.fstabSpec)
self._safeExecWithRedirect("ostree", set_kargs_args)
# Here we run ostree from the target system, because the
bootloader
# code for GRUB2 needs to run grub2-mkconfig.
self._safeExecWithRedirect("ostree", set_kargs_args,
root=iutil.getSysroot())
On Thu, Oct 16, 2014, at 08:55 AM, Radek Vykydal wrote:
Looks OK to me, I don't see anything that would break things. I would rename the physboot though.
New patch with rename of physboot:
From 248894abfa6ca5d23488c6f64d70a00b6188ba63 Mon Sep 17 00:00:00 2001
From: Colin Walters walters@verbum.org Date: Mon, 13 Oct 2014 21:01:23 -0400 Subject: [PATCH] Handle the case of rpmostreepayload + GRUB2
NOTE: Incompatible change for trees constructed prior to NOTE: https://github.com/projectatomic/rpm-ostree/pull/35
For rpmostreepayload (in contrast to yum mainline) is that Anaconda lays down the bootloader data and computes the kernel arguments, but ostree takes care of writing the configuration file (as it does on upgrades as well).
However, the handling of /boot in OSTree was a bit broken, and trying to support GRUB2 forced this change, because we need to ultimately execute grub2-mkconfig in the chroot and we need both the *real* /boot as well as the new /usr/lib/ostree-boot.
We switch to keeping /boot in the target root, and call ostree from there. This should still work for extlinux because we're just rewriting a config file.
For moving the GRUB2 config file, see a similar change for rpmostreepayload+extlinux in commit: 627486c22cdaf6c07009026791f5bd6fc1aaadaa
Note: This commit is only useful on BIOS systems as of yet. --- pyanaconda/bootloader.py | 9 +++---- pyanaconda/install.py | 17 ------------- pyanaconda/packaging/rpmostreepayload.py | 41 +++++++++++++++++++++----------- 3 files changed, 32 insertions(+), 35 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py index b021067..8cdbd2f 100644 --- a/pyanaconda/bootloader.py +++ b/pyanaconda/bootloader.py @@ -1547,10 +1547,11 @@ class GRUB2(GRUB): log.error("boot loader password setup failed: %s", e)
# make sure the default entry is the OS we are installing - entry_title = "0" - rc = iutil.execInSysroot("grub2-set-default", [entry_title]) - if rc: - log.error("failed to set default menu entry to %s", productName) + if self.default is not None: + entry_title = "0" + rc = iutil.execInSysroot("grub2-set-default", [entry_title]) + if rc: + log.error("failed to set default menu entry to %s", productName)
# now tell grub2 to generate the main configuration file rc = iutil.execInSysroot("grub2-mkconfig", diff --git a/pyanaconda/install.py b/pyanaconda/install.py index 40ead97..94f4663 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -118,20 +118,6 @@ def doConfiguration(storage, payload, ksdata, instClass):
progress_complete()
-def moveBootMntToPhysical(storage): - """Move the /boot mount to /mnt/sysimage/boot.""" - if iutil.getSysroot() == iutil.getTargetPhysicalRoot(): - return - - mounts = [storage.mountpoints.get("/boot/efi"), storage.mountpoints.get("/boot")] - for mnt in mounts: - if mnt is None: - return - - mnt.format.teardown() - mnt.teardown() - mnt.format.setup(options=mnt.format.options, chroot=iutil.getTargetPhysicalRoot()) - def doInstall(storage, payload, ksdata, instClass): """Perform an installation. This method takes the ksdata as prepared by the UI (the first hub, in graphical mode) and applies it to the disk. @@ -266,9 +252,6 @@ def doInstall(storage, payload, ksdata, instClass): writeBootLoader(storage, payload, instClass, ksdata)
with progress_report(_("Performing post-installation setup tasks")): - # Now, let's reset the state here so that the payload has - # /boot in the system root. - moveBootMntToPhysical(storage) payload.postInstall()
progress_complete() diff --git a/pyanaconda/packaging/rpmostreepayload.py b/pyanaconda/packaging/rpmostreepayload.py index 70a4903..37cf5b8 100644 --- a/pyanaconda/packaging/rpmostreepayload.py +++ b/pyanaconda/packaging/rpmostreepayload.py @@ -219,32 +219,45 @@ class RPMOSTreePayload(ArchivePayload): def postInstall(self): super(RPMOSTreePayload, self).postInstall()
- physboot = iutil.getTargetPhysicalRoot() + '/boot' + boot = iutil.getSysroot() + '/boot'
# If we're using extlinux, rename extlinux.conf to # syslinux.cfg, since that's what OSTree knows about. # syslinux upstream supports both, but I'd say that upstream # using syslinux.cfg is somewhat preferred. - physboot_extlinux = physboot + '/extlinux' - if os.path.isdir(physboot_extlinux): - physboot_syslinux = physboot + '/syslinux' - physboot_loader = physboot + '/loader' - assert os.path.isdir(physboot_loader) - orig_extlinux_conf = physboot_extlinux + '/extlinux.conf' - target_syslinux_cfg = physboot_loader + '/syslinux.cfg' + boot_extlinux = boot + '/extlinux' + if os.path.isdir(boot_extlinux): + boot_syslinux = boot + '/syslinux' + boot_loader = boot + '/loader' + assert os.path.isdir(boot_loader) + orig_extlinux_conf = boot_extlinux + '/extlinux.conf' + target_syslinux_cfg = boot_loader + '/syslinux.cfg' log.info("Moving %s -> %s", orig_extlinux_conf, target_syslinux_cfg) os.rename(orig_extlinux_conf, target_syslinux_cfg) # A compatibility bit for OSTree - os.mkdir(physboot_syslinux) - os.symlink('../loader/syslinux.cfg', physboot_syslinux + '/syslinux.cfg') + os.mkdir(boot_syslinux) + os.symlink('../loader/syslinux.cfg', boot_syslinux + '/syslinux.cfg') # And *also* tell syslinux that the config is really in /boot/loader - os.symlink('loader/syslinux.cfg', physboot + '/syslinux.cfg') + os.symlink('loader/syslinux.cfg', boot + '/syslinux.cfg') + + # And if we're using GRUB2, move its config file, also with a + # compatibility symlink. + boot_grub2 = boot + '/grub2' + if os.path.isdir(boot_grub2): + boot_loader = boot + '/loader' + assert os.path.isdir(boot_loader) + orig_grub_cfg = boot_grub2 + '/grub.cfg' + target_grub_cfg = boot_loader + '/grub.cfg' + log.info("Moving %s -> %s", orig_grub_cfg, target_grub_cfg) + os.rename(orig_grub_cfg, target_grub_cfg) + os.symlink('../loader/grub.cfg', orig_grub_cfg)
# OSTree owns the bootloader configuration, so here we give it # the argument list we computed from storage, architecture and # such. - set_kargs_args = ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), - "instutil", "set-kargs"] + set_kargs_args = ["admin", "instutil", "set-kargs"] set_kargs_args.extend(self.storage.bootloader.boot_args) set_kargs_args.append("root=" + self.storage.rootDevice.fstabSpec) - self._safeExecWithRedirect("ostree", set_kargs_args) + # Here we run ostree from the target system, because the bootloader + # code for GRUB2 needs to run grub2-mkconfig. + self._safeExecWithRedirect("ostree", set_kargs_args, root=iutil.getSysroot())
On Thu, Oct 16, 2014 at 10:17:12AM -0400, Colin Walters wrote:
boot_extlinux = boot + '/extlinux'
if os.path.isdir(boot_extlinux):
boot_syslinux = boot + '/syslinux'
boot_loader = boot + '/loader'
assert os.path.isdir(boot_loader)
Why the assert? If that fails it's going to blow up the installation with a traceback. It would be better to handle the error in some clean way.
# And if we're using GRUB2, move its config file, also with a
# compatibility symlink.
boot_grub2 = boot + '/grub2'
if os.path.isdir(boot_grub2):
boot_loader = boot + '/loader'
assert os.path.isdir(boot_loader)
Same here.
On Thu, Oct 16, 2014, at 06:03 PM, Brian C. Lane wrote:
On Thu, Oct 16, 2014 at 10:17:12AM -0400, Colin Walters wrote:
boot_extlinux = boot + '/extlinux'
if os.path.isdir(boot_extlinux):
boot_syslinux = boot + '/syslinux'
boot_loader = boot + '/loader'
assert os.path.isdir(boot_loader)
Why the assert? If that fails it's going to blow up the installation with a traceback. It would be better to handle the error in some clean way.
What would be a clean way? I can't think of anything to do other than to fail hard.
This assertion actually isn't the most likely to trip - what seems more likely to break is grub2/extlinux change the location of their files and rpmostreepayload isn't changed.
But the only way I can think of to handle that is automated testing.
On Thu, Oct 16, 2014 at 06:10:01PM -0400, Colin Walters wrote:
On Thu, Oct 16, 2014, at 06:03 PM, Brian C. Lane wrote:
On Thu, Oct 16, 2014 at 10:17:12AM -0400, Colin Walters wrote:
boot_extlinux = boot + '/extlinux'
if os.path.isdir(boot_extlinux):
boot_syslinux = boot + '/syslinux'
boot_loader = boot + '/loader'
assert os.path.isdir(boot_loader)
Why the assert? If that fails it's going to blow up the installation with a traceback. It would be better to handle the error in some clean way.
What would be a clean way? I can't think of anything to do other than to fail hard.
This assertion actually isn't the most likely to trip - what seems more likely to break is grub2/extlinux change the location of their files and rpmostreepayload isn't changed.
But the only way I can think of to handle that is automated testing.
Take a look at the errorHandler code used in the other payloads:
if errorHandler.cb(exn) == ERROR_RAISE:
On Thu, Oct 16, 2014, at 06:31 PM, Brian C. Lane wrote:
Take a look at the errorHandler code used in the other payloads:
if errorHandler.cb(exn) == ERROR_RAISE:
From what I can tell that's used when the code path could occur at
runtime as a result of dynamic conditions: erroneous user input, corrupted packages, unreachable network addresses, etc.
This assertion could only occur if ostree was buggy - it should always write /boot/loader regardless of whatever the user input. I could just remove the assertions I guess, there's lots of other equivalent bits that would also traceback.
Right?
On Thu, Oct 16, 2014 at 07:05:52PM -0400, Colin Walters wrote:
On Thu, Oct 16, 2014, at 06:31 PM, Brian C. Lane wrote:
Take a look at the errorHandler code used in the other payloads:
if errorHandler.cb(exn) == ERROR_RAISE:
From what I can tell that's used when the code path could occur at runtime as a result of dynamic conditions: erroneous user input, corrupted packages, unreachable network addresses, etc.
This assertion could only occur if ostree was buggy - it should always write /boot/loader regardless of whatever the user input. I could just remove the assertions I guess, there's lots of other equivalent bits that would also traceback.
Right?
Isn't that the same as if we hit corrupt packages from a repo? Maybe there needs to be a ostree sanity check someplace in the process that would present a nice error.
I know we've got piles of places where we traceback, I'd just like to head off any new ones when possible.
On Thu, Oct 16, 2014, at 07:15 PM, Brian C. Lane wrote:
Isn't that the same as if we hit corrupt packages from a repo?
No, I believe this condition could only occur as a result of ostree itself being buggy.
Corruption from pull is covered already, and things like ENOSPC in deploy are covered by _safeExecWithRedirect.
"ostree admin deploy" is what updates the /boot/loader symlinks.
I know we've got piles of places where we traceback, I'd just like to head off any new ones when possible.
That makes sense! I do not believe this is one of those cases however.
Though it looks like very little in anaconda uses "assert" outside of the tests. Better to just remove?
On Thu, Oct 16, 2014 at 07:22:57PM -0400, Colin Walters wrote:
On Thu, Oct 16, 2014, at 07:15 PM, Brian C. Lane wrote:
Isn't that the same as if we hit corrupt packages from a repo?
No, I believe this condition could only occur as a result of ostree itself being buggy.
Corruption from pull is covered already, and things like ENOSPC in deploy are covered by _safeExecWithRedirect.
"ostree admin deploy" is what updates the /boot/loader symlinks.
Ah, ok.
I know we've got piles of places where we traceback, I'd just like to head off any new ones when possible.
That makes sense! I do not believe this is one of those cases however.
Though it looks like very little in anaconda uses "assert" outside of the tests. Better to just remove?
Yeah, I suppose so.
Updated patch (as yet still untested in rawhide/f21):
From d7388c95135989160200a4990bd7bc07d9394622 Mon Sep 17 00:00:00 2001
From: Colin Walters walters@verbum.org Date: Mon, 13 Oct 2014 21:01:23 -0400 Subject: [PATCH] Handle the case of rpmostreepayload + GRUB2
NOTE: Incompatible change for trees constructed prior to NOTE: https://github.com/projectatomic/rpm-ostree/pull/35
For rpmostreepayload (in contrast to yum mainline) is that Anaconda lays down the bootloader data and computes the kernel arguments, but ostree takes care of writing the configuration file (as it does on upgrades as well).
However, the handling of /boot in OSTree was a bit broken, and trying to support GRUB2 forced this change, because we need to ultimately execute grub2-mkconfig in the chroot and we need both the *real* /boot as well as the new /usr/lib/ostree-boot.
We switch to keeping /boot in the target root, and call ostree from there. This should still work for extlinux because we're just rewriting a config file.
For moving the GRUB2 config file, see a similar change for rpmostreepayload+extlinux in commit: 627486c22cdaf6c07009026791f5bd6fc1aaadaa
Note: This commit is only useful on BIOS systems as of yet. --- pyanaconda/bootloader.py | 9 ++++---- pyanaconda/install.py | 17 -------------- pyanaconda/packaging/rpmostreepayload.py | 39 ++++++++++++++++++++------------ 3 files changed, 30 insertions(+), 35 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py index b021067..8cdbd2f 100644 --- a/pyanaconda/bootloader.py +++ b/pyanaconda/bootloader.py @@ -1547,10 +1547,11 @@ class GRUB2(GRUB): log.error("boot loader password setup failed: %s", e)
# make sure the default entry is the OS we are installing - entry_title = "0" - rc = iutil.execInSysroot("grub2-set-default", [entry_title]) - if rc: - log.error("failed to set default menu entry to %s", productName) + if self.default is not None: + entry_title = "0" + rc = iutil.execInSysroot("grub2-set-default", [entry_title]) + if rc: + log.error("failed to set default menu entry to %s", productName)
# now tell grub2 to generate the main configuration file rc = iutil.execInSysroot("grub2-mkconfig", diff --git a/pyanaconda/install.py b/pyanaconda/install.py index 40ead97..94f4663 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -118,20 +118,6 @@ def doConfiguration(storage, payload, ksdata, instClass):
progress_complete()
-def moveBootMntToPhysical(storage): - """Move the /boot mount to /mnt/sysimage/boot.""" - if iutil.getSysroot() == iutil.getTargetPhysicalRoot(): - return - - mounts = [storage.mountpoints.get("/boot/efi"), storage.mountpoints.get("/boot")] - for mnt in mounts: - if mnt is None: - return - - mnt.format.teardown() - mnt.teardown() - mnt.format.setup(options=mnt.format.options, chroot=iutil.getTargetPhysicalRoot()) - def doInstall(storage, payload, ksdata, instClass): """Perform an installation. This method takes the ksdata as prepared by the UI (the first hub, in graphical mode) and applies it to the disk. @@ -266,9 +252,6 @@ def doInstall(storage, payload, ksdata, instClass): writeBootLoader(storage, payload, instClass, ksdata)
with progress_report(_("Performing post-installation setup tasks")): - # Now, let's reset the state here so that the payload has - # /boot in the system root. - moveBootMntToPhysical(storage) payload.postInstall()
progress_complete() diff --git a/pyanaconda/packaging/rpmostreepayload.py b/pyanaconda/packaging/rpmostreepayload.py index 70a4903..c940ab1 100644 --- a/pyanaconda/packaging/rpmostreepayload.py +++ b/pyanaconda/packaging/rpmostreepayload.py @@ -219,32 +219,43 @@ class RPMOSTreePayload(ArchivePayload): def postInstall(self): super(RPMOSTreePayload, self).postInstall()
- physboot = iutil.getTargetPhysicalRoot() + '/boot' + boot = iutil.getSysroot() + '/boot'
# If we're using extlinux, rename extlinux.conf to # syslinux.cfg, since that's what OSTree knows about. # syslinux upstream supports both, but I'd say that upstream # using syslinux.cfg is somewhat preferred. - physboot_extlinux = physboot + '/extlinux' - if os.path.isdir(physboot_extlinux): - physboot_syslinux = physboot + '/syslinux' - physboot_loader = physboot + '/loader' - assert os.path.isdir(physboot_loader) - orig_extlinux_conf = physboot_extlinux + '/extlinux.conf' - target_syslinux_cfg = physboot_loader + '/syslinux.cfg' + boot_extlinux = boot + '/extlinux' + if os.path.isdir(boot_extlinux): + boot_syslinux = boot + '/syslinux' + boot_loader = boot + '/loader' + orig_extlinux_conf = boot_extlinux + '/extlinux.conf' + target_syslinux_cfg = boot_loader + '/syslinux.cfg' log.info("Moving %s -> %s", orig_extlinux_conf, target_syslinux_cfg) os.rename(orig_extlinux_conf, target_syslinux_cfg) # A compatibility bit for OSTree - os.mkdir(physboot_syslinux) - os.symlink('../loader/syslinux.cfg', physboot_syslinux + '/syslinux.cfg') + os.mkdir(boot_syslinux) + os.symlink('../loader/syslinux.cfg', boot_syslinux + '/syslinux.cfg') # And *also* tell syslinux that the config is really in /boot/loader - os.symlink('loader/syslinux.cfg', physboot + '/syslinux.cfg') + os.symlink('loader/syslinux.cfg', boot + '/syslinux.cfg') + + # And if we're using GRUB2, move its config file, also with a + # compatibility symlink. + boot_grub2 = boot + '/grub2' + if os.path.isdir(boot_grub2): + boot_loader = boot + '/loader' + orig_grub_cfg = boot_grub2 + '/grub.cfg' + target_grub_cfg = boot_loader + '/grub.cfg' + log.info("Moving %s -> %s", orig_grub_cfg, target_grub_cfg) + os.rename(orig_grub_cfg, target_grub_cfg) + os.symlink('../loader/grub.cfg', orig_grub_cfg)
# OSTree owns the bootloader configuration, so here we give it # the argument list we computed from storage, architecture and # such. - set_kargs_args = ["admin", "--sysroot=" + iutil.getTargetPhysicalRoot(), - "instutil", "set-kargs"] + set_kargs_args = ["admin", "instutil", "set-kargs"] set_kargs_args.extend(self.storage.bootloader.boot_args) set_kargs_args.append("root=" + self.storage.rootDevice.fstabSpec) - self._safeExecWithRedirect("ostree", set_kargs_args) + # Here we run ostree from the target system, because the bootloader + # code for GRUB2 needs to run grub2-mkconfig. + self._safeExecWithRedirect("ostree", set_kargs_args, root=iutil.getSysroot())
On Thu, Oct 16, 2014 at 08:55:27PM -0400, Colin Walters wrote:
And it was corrupted by line wrapping, sending attached.
From d7388c95135989160200a4990bd7bc07d9394622 Mon Sep 17 00:00:00 2001 From: Colin Walters walters@verbum.org Date: Mon, 13 Oct 2014 21:01:23 -0400 Subject: [PATCH] Handle the case of rpmostreepayload + GRUB2
Ack.
anaconda-patches@lists.fedorahosted.org