Skip to content

Commit

Permalink
Add support for erofs
Browse files Browse the repository at this point in the history
erofs is an alternative readonly filesystem that can be
used as alternative to squashfs. This Fixes #2633
  • Loading branch information
schaefi committed Sep 13, 2024
1 parent be61740 commit 8535e4e
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 36 deletions.
40 changes: 40 additions & 0 deletions build-tests/x86/rawhide/test-image-erofs/appliance.kiwi
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>

<image schemaversion="7.5" name="kiwi-test-image-erofs">
<description type="system">
<author>Marcus Schaefer</author>
<contact>[email protected]</contact>
<specification>Fedora Appliance, Testing erofs filesystem image</specification>
</description>
<preferences>
<version>2.0.0</version>
<packagemanager>dnf5</packagemanager>
<rpm-check-signatures>false</rpm-check-signatures>
</preferences>
<preferences>
<type image="erofs"/>
</preferences>
<users>
<user password="$1$wYJUgpM5$RXMMeASDc035eX.NbYWFl0" home="/root" name="root" groups="root"/>
</users>
<repository type="rpm-md" alias="kiwi-next-generation" priority="1">
<source path="obs://Virtualization:Appliances:Staging/Fedora_Rawhide"/>
</repository>
<repository type="rpm-md" alias="Fedora_Rawhide">
<source path="obs://Fedora:Rawhide/standard"/>
</repository>
<packages type="image">
<package name="kernel"/>
<package name="selinux-policy-targeted"/>
<package name="dhclient"/>
<package name="glibc-all-langpacks"/>
<package name="vim"/>
<package name="tzdata"/>
<package name="NetworkManager"/>
</packages>
<packages type="bootstrap">
<package name="filesystem"/>
<package name="basesystem"/>
<package name="fedora-release"/>
</packages>
</image>
8 changes: 7 additions & 1 deletion build-tests/x86/rawhide/test-image-live-disk/appliance.kiwi
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</description>
<profiles>
<profile name="Live" description="Live image of Fedora Rawhide"/>
<profile name="LiveEroFS" description="Live Root via EroFS"/>
<profile name="Virtual" description="Virtual image of Fedora Rawhide"/>
<profile name="Disk" description="OEM image of Fedora Rawhide"/>
</profiles>
Expand All @@ -24,6 +25,11 @@
<timezone>UTC</timezone>
<rpm-check-signatures>false</rpm-check-signatures>
</preferences>
<preferences profiles="LiveEroFS">
<type image="iso" flags="overlay" firmware="uefi" hybridpersistent_filesystem="ext4" hybridpersistent="true" kernelcmdline="console=ttyS0" filesystem="erofs" erofscompression="zstd,level=12">
<bootloader name="grub2" console="serial" timeout="10"/>
</type>
</preferences>
<preferences profiles="Live">
<type image="iso" flags="overlay" firmware="uefi" hybridpersistent_filesystem="ext4" hybridpersistent="true" kernelcmdline="console=ttyS0">
<bootloader name="grub2" console="serial" timeout="10"/>
Expand Down Expand Up @@ -71,7 +77,7 @@
<package name="tzdata"/>
<package name="NetworkManager"/>
</packages>
<packages type="image" profiles="Live">
<packages type="image" profiles="Live,LiveEroFS">
<package name="dracut-kiwi-live"/>
</packages>
<packages type="image" profiles="Disk">
Expand Down
9 changes: 8 additions & 1 deletion build-tests/x86/tumbleweed/test-image-live/appliance.kiwi
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<profile name="Standard" description="Standard EFI/BIOS Live Boot"/>
<profile name="Secure" description="SecureBoot/BIOS Live Boot"/>
<profile name="SDBoot" description="EFI Boot via systemd-boot"/>
<profile name="EroFS" description="Live Root via EroFS"/>
</profiles>
<preferences>
<version>1.42.3</version>
Expand All @@ -31,6 +32,11 @@
<bootloader name="systemd_boot"/>
</type>
</preferences>
<preferences profiles="EroFS">
<type image="iso" flags="overlay" firmware="efi" kernelcmdline="console=ttyS0" hybridpersistent_filesystem="ext4" hybridpersistent="true" mediacheck="true" filesystem="erofs">
<bootloader name="grub2" console="serial" timeout="10"/>
</type>
</preferences>
<preferences profiles="Standard">
<type image="iso" flags="overlay" firmware="efi" kernelcmdline="console=ttyS0" hybridpersistent_filesystem="ext4" hybridpersistent="true" mediacheck="true">
<bootloader name="grub2" console="serial" timeout="10"/>
Expand All @@ -50,14 +56,15 @@
<packages type="image" profiles="SDBoot">
<package name="systemd-boot"/>
</packages>
<packages type="image" profiles="Standard,Secure">
<packages type="image" profiles="Standard,Secure,EroFS">
<package name="grub2-branding-openSUSE"/>
<package name="grub2"/>
<package name="grub2-x86_64-efi" arch="x86_64"/>
<package name="grub2-i386-pc"/>
<package name="shim"/>
</packages>
<packages type="image">
<package name="curl"/>
<package name="bind-utils"/>
<package name="patterns-openSUSE-base"/>
<package name="procps"/>
Expand Down
39 changes: 13 additions & 26 deletions build-tests/x86/tumbleweed/test-image-live/config.sh
Original file line number Diff line number Diff line change
@@ -1,39 +1,26 @@
#!/bin/bash
#================
# FILE : config.sh
#----------------
# PROJECT : OpenSuSE KIWI Image System
# COPYRIGHT : (c) 2006 SUSE LINUX Products GmbH. All rights reserved
# :
# AUTHOR : Marcus Schaefer <[email protected]>
# :
# BELONGS TO : Operating System images
# :
# DESCRIPTION : configuration script for SUSE based
# : operating systems
#----------------
#======================================
# Functions...
#--------------------------------------
test -f /.kconfig && . /.kconfig
test -f /.profile && . /.profile

set -ex

declare kiwi_profiles=${kiwi_profiles}
declare kiwi_iname=${kiwi_iname}

#======================================
# Greeting...
#--------------------------------------
echo "Configure image: [$kiwi_iname]..."

#======================================
# Setup baseproduct link
#--------------------------------------
suseSetupProduct

#======================================
# Activate services
#--------------------------------------
suseInsertService sshd
systemctl enable sshd

#======================================
# Setup default target, multi-user
# Include erofs module
#--------------------------------------
baseSetRunlevel 3
for profile in ${kiwi_profiles//,/ }; do
if [ "${profile}" = "EroFS" ]; then
# remove from blacklist
rm -f /usr/lib/modprobe.d/60-blacklist_fs-erofs.conf
fi
done
2 changes: 1 addition & 1 deletion kiwi/builder/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def __init__(
self.blocksize = xml_state.build_type.get_target_blocksize()
self.filesystem_setup = FileSystemSetup(xml_state, root_dir)
self.filesystems_no_device_node = [
'squashfs'
'squashfs', 'erofs'
]
self.luks = xml_state.get_luks_credentials()
self.result = Result(xml_state)
Expand Down
13 changes: 11 additions & 2 deletions kiwi/builder/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def create(self) -> Result:
filesystem_setup = FileSystemSetup(
self.xml_state, self.root_dir
)
if root_filesystem != 'squashfs':
if root_filesystem not in ['squashfs', 'erofs']:
# Create a filesystem image of the specified type
# and put it into a SquashFS container
root_image = Temporary().new_file()
Expand Down Expand Up @@ -302,12 +302,15 @@ def create(self) -> Result:
else:
# Put the root filesystem into SquashFS directly
with FileSystem.new(
name='squashfs',
name=root_filesystem,
device_provider=DeviceProvider(),
root_dir=self.root_dir + os.sep,
custom_args={
'compression':
self.xml_state.build_type.get_squashfscompression()
} if root_filesystem == 'squashfs' else {
'compression':
self.xml_state.build_type.get_erofscompression()
}
) as live_container_image:
container_image = Temporary().new_file()
Expand All @@ -316,6 +319,12 @@ def create(self) -> Result:
)
Path.create(self.media_dir.name + '/LiveOS')
os.chmod(container_image.name, 0o644)
# Note: we keep the filename of the read-only image as it is
# even if another read-only filesystem not matching this
# filename is used. This is because the following filename
# is also used in the initrd code for the kiwi-live and
# dmsquash dracut modules. The name can be overwritten
# with the rd.live.squashimg boot option though.
shutil.copy(
container_image.name,
self.media_dir.name + '/LiveOS/squashfs.img'
Expand Down
2 changes: 1 addition & 1 deletion kiwi/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ def get_filesystem_image_types():
"""
return [
'ext2', 'ext3', 'ext4', 'btrfs', 'squashfs',
'xfs', 'fat16', 'fat32'
'xfs', 'fat16', 'fat32', 'erofs'
]

@staticmethod
Expand Down
3 changes: 2 additions & 1 deletion kiwi/filesystem/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ def new(
'fat16': 'Fat16',
'fat32': 'Fat32',
'squashfs': 'SquashFs',
'swap': 'Swap'
'swap': 'Swap',
'erofs': 'EroFs'
}
try:
filesystem = importlib.import_module(
Expand Down
60 changes: 60 additions & 0 deletions kiwi/filesystem/erofs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Copyright (c) 2024 SUSE Software Solutions Germany GmbH. All rights reserved.
#
# This file is part of kiwi.
#
# kiwi is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# kiwi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
#
from typing import List

# project
from kiwi.filesystem.base import FileSystemBase
from kiwi.command import Command


class FileSystemEroFs(FileSystemBase):
"""
**Implements creation of erofs filesystem**
"""
def create_on_file(
self, filename, label: str = None, exclude: List[str] = None
):
"""
Create erofs filesystem from data tree
:param string filename: result file path name
:param string label: volume label
:param list exclude: list of exclude dirs/files
"""
self.filename = filename
exclude_options = []
compression = self.custom_args.get('compression')
if compression:
self.custom_args['create_options'].append('-z')
self.custom_args['create_options'].append(compression)

if exclude:
for item in exclude:
exclude_options.append(f'--exclude-regex={item}')

if label:
self.custom_args['create_options'].append('-L')
self.custom_args['create_options'].append(label)

Command.run(
[
'mkfs.erofs'
] + self.custom_args['create_options'] + exclude_options + [
self.filename, self.root_dir
]
)
12 changes: 10 additions & 2 deletions kiwi/schema/kiwi.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -1671,7 +1671,7 @@ div {
k.type.filesystem.attribute =
## Specifies the root filesystem type
attribute filesystem {
"btrfs" | "ext2" | "ext3" | "ext4" | "squashfs" | "xfs"
"btrfs" | "ext2" | "ext3" | "ext4" | "squashfs" | "erofs" | "xfs"
}
>> sch:pattern [ id = "filesystem" is-a = "image_type"
sch:param [ name = "attr" value = "filesystem" ]
Expand All @@ -1682,6 +1682,13 @@ div {
sch:param [ name = "attr" value = "filesystem" ]
sch:param [ name = "types" value = "oem" ]
]
k.type.erofscompression.attribute =
## Specifies the compression type for erofs
attribute erofscompression { text }
>> sch:pattern [ id = "erofscompression" is-a = "image_type"
sch:param [ name = "attr" value = "erofscompression" ]
sch:param [ name = "types" value = "oem pxe kis iso erofs" ]
]
k.type.squashfscompression.attribute =
## Specifies the compression type for mksquashfs
attribute squashfscompression {
Expand Down Expand Up @@ -1958,7 +1965,7 @@ div {
## Specifies the image type
attribute image {
"btrfs" | "cpio" | "docker" | "ext2" | "ext3" |
"ext4" | "iso" | "oem" | "pxe" | "kis" | "squashfs" | "tbz" |
"ext4" | "iso" | "oem" | "pxe" | "kis" | "squashfs" | "erofs" | "tbz" |
"xfs" | "oci" | "appx" | "enclave"
}
>> sch:pattern [
Expand Down Expand Up @@ -2284,6 +2291,7 @@ div {
k.type.fsmountoptions.attribute? &
k.type.fscreateoptions.attribute? &
k.type.squashfscompression.attribute? &
k.type.erofscompression.attribute? &
k.type.gcelicense.attribute? &
k.type.hybridpersistent.attribute? &
k.type.hybridpersistent_filesystem.attribute? &
Expand Down
14 changes: 14 additions & 0 deletions kiwi/schema/kiwi.rng
Original file line number Diff line number Diff line change
Expand Up @@ -2435,6 +2435,7 @@ structure</a:documentation>
<value>ext3</value>
<value>ext4</value>
<value>squashfs</value>
<value>erofs</value>
<value>xfs</value>
</choice>
</attribute>
Expand All @@ -2447,6 +2448,15 @@ structure</a:documentation>
<sch:param name="types" value="oem"/>
</sch:pattern>
</define>
<define name="k.type.erofscompression.attribute">
<attribute name="erofscompression">
<a:documentation>Specifies the compression type for erofs</a:documentation>
</attribute>
<sch:pattern id="erofscompression" is-a="image_type">
<sch:param name="attr" value="erofscompression"/>
<sch:param name="types" value="oem pxe kis iso erofs"/>
</sch:pattern>
</define>
<define name="k.type.squashfscompression.attribute">
<attribute name="squashfscompression">
<a:documentation>Specifies the compression type for mksquashfs</a:documentation>
Expand Down Expand Up @@ -2822,6 +2832,7 @@ initrd architecture.</a:documentation>
<value>pxe</value>
<value>kis</value>
<value>squashfs</value>
<value>erofs</value>
<value>tbz</value>
<value>xfs</value>
<value>oci</value>
Expand Down Expand Up @@ -3310,6 +3321,9 @@ kiwi-ng result bundle ...</a:documentation>
<optional>
<ref name="k.type.squashfscompression.attribute"/>
</optional>
<optional>
<ref name="k.type.erofscompression.attribute"/>
</optional>
<optional>
<ref name="k.type.gcelicense.attribute"/>
</optional>
Expand Down
Loading

0 comments on commit 8535e4e

Please sign in to comment.