-
Notifications
You must be signed in to change notification settings - Fork 9
Add customize command #164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if it wouldn't have been easier to simply repack the ISO in a single xorriso call, something similar to what the seedimage does in classic Elemental.
xorriso -indev <inputISO> -outdev <outputISO> -map /overlay/ / -boot_image any replay
The above command would add/overwrite the contents of the /overlay
folder in host to the root of the ISO filesystem. If we can limit our customizations there then the process is way faster, reuses the already existing ISO contents without re-generating them (squashfs, EFI partitions, etc.) and narrows the changes applied to the resulting image.
what do you think?
pkg/installermedia/iso.go
Outdated
return fmt.Errorf("failed extracting ISO fs: %w", err) | ||
} | ||
|
||
err = i.extractSquashRootfs(isoDir, rootDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this extracting entirely the squashfs image content to actually squash it again later on without any modification?
Modifying the squashfs should not be allowed in any case, I think. Moreover if we keep the squashfs image untouched the process will be way faster to my understanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, since we are not dealing with a golden image repacking should be a noop unless we add extra information as stated before.
pkg/installermedia/iso.go
Outdated
return nil | ||
} | ||
|
||
func (i ISO) extractSquashRootfs(isoDir, rootDir string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I struggle to see why we need this part...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not constructive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry my bad, should have explained what I had in mind.
I was trying to say I don't see the need of unpacking the squashfs file system and then resquash it back again. As far as I understand we only need to unpack the filesystem to run the bootloader installation, for which we can only modify the kernel command line setup.
Unless I am missing something the customize process does not allow changing the rootfs contents hence this results into a uncompress -> copy -> recompress -> copy sequence, just to update a kernel command line which is not part of the squashed image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I am missing something the customize process does not allow changing the rootfs contents hence this results into a uncompress -> copy -> recompress -> copy sequence, just to update a kernel command line which is not part of the squashed image.
Where is this described for the customize process? I have been trying to find docs about this process, but have not been successful in finding anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we have it described anywhere yet 😞
In my head (and this is only MY understanding) this is allowing to produce an auto installable ISO (from a given ISO built in OBS) that runs an installation on first boot resulting in to a setup equivalent to what is achievable by elemental build
. So my first iteration would be to make it similar to the build-iso command INPUT wise, so it can set the target device, config script, etc. Which essentially means adding some parameters to the current given ISO.
So as user, I get and ISO, I run customize with my custom parameters and the result is an ISO which self installs on first boot.
At least this is how I imagined it... but you are right, I don't think we have it well defined anywhere.
In a wider picture I guess this is should be used by elemental build
instead of actually running an installation.
pkg/installermedia/iso.go
Outdated
return fmt.Errorf("failed preparing iso directory tree: %w", err) | ||
} | ||
|
||
err = i.prepareEFI(isoDir, efiDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is required only to set the kernel command line in case of changes... I am wondering if shouldn't the keep the kernel cmd line in the ISO filesystem as a grub variable or similar. This way we could even omit having to recreate the EFI partition too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that would be another way to solve this.
Sure it would have been easier, but not allow the same level of customization. The thinking here was to open the way to customize the rootfs in case things such as extra binaries or kernel-modules are needed. Regenerating the squashfs and EFI-partitions should not be a problem, since we use the same input it should produce the same output. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure it would have been easier, but not allow the same level of customization. The thinking here was to open the way to customize the rootfs in case things such as extra binaries or kernel-modules are needed.
I understand, but if rootfs refers to the OS tree then I don't see how to keep those changes across updates... 🤔 Moreover, if I understand it correctly, the OverlayTree applies on the ISO filesystem, not over the squashfs tree. So the contents of the squashfs image can't be modified anyway.
Regenerating the squashfs and EFI-partitions should not be a problem, since we use the same input it should produce the same output.
I agree the result would be equivalent, however rebuilding the squashfs is a CPU demanding process.
pkg/installermedia/iso.go
Outdated
return nil | ||
} | ||
|
||
func (i ISO) extractSquashRootfs(isoDir, rootDir string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry my bad, should have explained what I had in mind.
I was trying to say I don't see the need of unpacking the squashfs file system and then resquash it back again. As far as I understand we only need to unpack the filesystem to run the bootloader installation, for which we can only modify the kernel command line setup.
Unless I am missing something the customize process does not allow changing the rootfs contents hence this results into a uncompress -> copy -> recompress -> copy sequence, just to update a kernel command line which is not part of the squashed image.
@@ -225,7 +341,7 @@ func (i ISO) prepareRoot(rootDir string) error { | |||
|
|||
err = selinux.Relabel(i.ctx, i.s, rootDir) | |||
if err != nil { | |||
return fmt.Errorf("SELinux labelling failed: %w", err) | |||
i.s.Logger().Warn("Error selinux relabelling: %s", err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I needed this to be able to build a new ISO without errors. When this fails we also need to add selinux=0 to command-line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting... SE Linux is also hitting me with the ISO build in OBS, I guess we will need to make an effort on that front to understand and review where we can actually improve SE Linux setup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is good, great work.
Simple and flexible enough to actually test and refine the actual use cases and flows we need.
@@ -225,7 +341,7 @@ func (i ISO) prepareRoot(rootDir string) error { | |||
|
|||
err = selinux.Relabel(i.ctx, i.s, rootDir) | |||
if err != nil { | |||
return fmt.Errorf("SELinux labelling failed: %w", err) | |||
i.s.Logger().Warn("Error selinux relabelling: %s", err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting... SE Linux is also hitting me with the ISO build in OBS, I guess we will need to make an effort on that front to understand and review where we can actually improve SE Linux setup.
pkg/installermedia/iso.go
Outdated
return nil | ||
} | ||
|
||
func (i ISO) extractSquashRootfs(isoDir, rootDir string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we have it described anywhere yet 😞
In my head (and this is only MY understanding) this is allowing to produce an auto installable ISO (from a given ISO built in OBS) that runs an installation on first boot resulting in to a setup equivalent to what is achievable by elemental build
. So my first iteration would be to make it similar to the build-iso command INPUT wise, so it can set the target device, config script, etc. Which essentially means adding some parameters to the current given ISO.
So as user, I get and ISO, I run customize with my custom parameters and the result is an ISO which self installs on first boot.
At least this is how I imagined it... but you are right, I don't think we have it well defined anywhere.
In a wider picture I guess this is should be used by elemental build
instead of actually running an installation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. This establishes a good base that we can build upon -- I expect the input to eventually be the configuration directory currently used for the build command but we will figure this out later.
Found one minor issue in one of the tests. Happy to approve as soon as this is fixed.
The customize command can be used to customize a pre-built installer image (right now only ISO supported). Use single call to xorriso to map files onto the ISO. Write a grubenv to /boot/grub2/grubenv with extra_cmdline parameter used by grub_live.cfg. Also overwrite /LiveOS/setup.sh with file provided in --config and map the passed in --overlay over / Signed-off-by: Fredrik Lönnegren <[email protected]>
0f58d93
to
68f2614
Compare
The customize command can be used to customize a pre-built installer
image (right now only ISO supported).
The customization process uses xorriso to add config files and overlays into the installer image.