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 45bb7d0
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 35 deletions.
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
12 changes: 9 additions & 3 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,20 +302,26 @@ 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': ''}
) as live_container_image:
container_image = Temporary().new_file()
live_container_image.create_on_file(
container_image.name
)
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
57 changes: 57 additions & 0 deletions kiwi/filesystem/erofs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# 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 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
]
)
4 changes: 2 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 Down Expand Up @@ -1958,7 +1958,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
2 changes: 2 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 Down Expand Up @@ -2822,6 +2823,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
4 changes: 4 additions & 0 deletions package/python-kiwi-spec-template
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ Provides: kiwi-filesystem:xfs
Requires: dosfstools
Requires: e2fsprogs
Requires: xfsprogs
%if ! (0%{?suse_version} && 0%{?suse_version} < 1600)
Provides: kiwi-filesystem:erofs
Requires: erofs-utils
%endif
%if 0%{?suse_version}
Requires: btrfsprogs
%else
Expand Down
36 changes: 36 additions & 0 deletions test/unit/filesystem/erofs_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from unittest.mock import patch

import unittest.mock as mock

from kiwi.defaults import Defaults
from kiwi.filesystem.erofs import FileSystemEroFs


class TestFileSystemEroFs:
@patch('os.path.exists')
def setup(self, mock_exists):
mock_exists.return_value = True
self.erofs = FileSystemEroFs(mock.Mock(), 'root_dir')

@patch('os.path.exists')
def setup_method(self, cls, mock_exists):
self.setup()

@patch('kiwi.filesystem.erofs.Command.run')
def test_create_on_file(self, mock_command):
Defaults.set_platform_name('x86_64')
self.erofs.create_on_file('myimage', 'label')
mock_command.assert_called_once_with(
['mkfs.erofs', '-L', 'label', 'myimage', 'root_dir']
)

@patch('kiwi.filesystem.erofs.Command.run')
def test_create_on_file_exclude_data(self, mock_command):
Defaults.set_platform_name('x86_64')
self.erofs.create_on_file('myimage', 'label', ['foo'])
mock_command.assert_called_once_with(
[
'mkfs.erofs', '-L', 'label',
'--exclude-regex=foo', 'myimage', 'root_dir'
]
)

0 comments on commit 45bb7d0

Please sign in to comment.