forked from OERV-BSP/image-builder
just work (TM)
This commit is contained in:
+8
-4
@@ -4,10 +4,14 @@ RUN sed -i 's/metalink=/# metalink=/g' /etc/yum.repos.d/openEuler.repo && \
|
||||
sed -i 's/repo.openeuler.org/mirror.isrc.ac.cn\/openeuler/g' /etc/yum.repos.d/openEuler.repo
|
||||
|
||||
RUN yum install -y \
|
||||
tar \
|
||||
zstd \
|
||||
gzip \
|
||||
xz \
|
||||
bzip2 \
|
||||
dosfstools \
|
||||
findutils \
|
||||
gdisk \
|
||||
gzip \
|
||||
rsync \
|
||||
tar \
|
||||
util-linux \
|
||||
xz \
|
||||
zstd \
|
||||
&& yum clean all
|
||||
|
||||
@@ -9,7 +9,7 @@ CONTAINER_CMD ?= docker
|
||||
CONTAINER_IMAGE_TAG ?= imagebuilder-openeuler-24.03-lts
|
||||
|
||||
define stack_include
|
||||
$$(info Makefile "$$(lastword $$(MAKEFILE_STACK))" includes "$1")
|
||||
#$$(info Makefile "$$(lastword $$(MAKEFILE_STACK))" includes "$1")
|
||||
MAKEFILE_STACK += $1
|
||||
CURRENT_MAKEFILE := $$(lastword $$(MAKEFILE_STACK))
|
||||
CURRENT_DIR := $$(dir $$(CURRENT_MAKEFILE))
|
||||
@@ -48,10 +48,33 @@ $(eval $(call stack_include,$(CURRENT_DIR)receipes/receipes.mk))
|
||||
.PHONY: all_rootfs
|
||||
all_rootfs: $(ROOTFS_TARGETS)
|
||||
|
||||
.PHONY: all_bsp
|
||||
all_bsp: $(BSP_TARGETS)
|
||||
|
||||
.PHONY: list_rootfs
|
||||
list_rootfs:
|
||||
@echo $(ROOTFS_TARGETS)
|
||||
|
||||
.PHONY: list_bsp
|
||||
list_bsp:
|
||||
@echo $(BSP_TARGETS)
|
||||
|
||||
.PHONY: list
|
||||
list:
|
||||
@echo "ROOTFS targets:"
|
||||
@echo "$(ROOTFS_TARGETS)" | tr ' ' '\n'
|
||||
@echo
|
||||
@echo "BSP targets:"
|
||||
@echo "$(BSP_TARGETS)" | tr ' ' '\n'
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf "$(WORK_DIR)"
|
||||
|
||||
.PHONY: clean_staging
|
||||
clean_staging:
|
||||
rm -rf "$(STAGING_DIR)"
|
||||
|
||||
.PHONY: container
|
||||
container:
|
||||
$(CONTAINER_CMD) build -t $(CONTAINER_IMAGE_TAG) $(ROOT_DIR)
|
||||
@@ -59,4 +82,5 @@ container:
|
||||
|
||||
.PHONY: .test
|
||||
.test:
|
||||
@echo $(MAKEFILE_STACK)
|
||||
@echo $(ROOTFS_TARGETS)
|
||||
@echo $(BSP_TARGETS)
|
||||
|
||||
+91
-13
@@ -41,6 +41,8 @@ ifndef RELEASE_NAME
|
||||
$$(error RELEASE_NAME not provided)
|
||||
endif
|
||||
|
||||
$$(DISTRO_NAME)_$$(RELEASE_NAME)_RECEIPES :=
|
||||
|
||||
undefine RELEASE_NAME
|
||||
endef
|
||||
|
||||
@@ -53,7 +55,7 @@ endif
|
||||
|
||||
# Cleanup and register new receipe
|
||||
undefine RECEIPE_NAME
|
||||
undefine ROOTFS_COMPRESSION
|
||||
undefine COMPRESSION
|
||||
undefine EXTENDS
|
||||
|
||||
$$(eval $$(call stack_include,$1/receipe.mk))
|
||||
@@ -63,16 +65,17 @@ ifndef RECEIPE_NAME
|
||||
$$(error RECEIPE_NAME not defined)
|
||||
endif
|
||||
# Check compression method
|
||||
ifeq ($$(ROOTFS_COMPRESSION),zstd)
|
||||
ROOTFS_COMPRESSION_SUFFIX := tar.zst
|
||||
ROOTFS_COMPRESSION_CMD := tar --use-compress-program=zstd -cf "$$$$$$$${OUTPUT_ARCHIVE}" -C "$$$$$$$${ROOTFS_DIR}" .
|
||||
ifeq ($$(COMPRESSION),zstd)
|
||||
COMPRESSION_SUFFIX := tar.zst
|
||||
COMPRESSION_CMD := tar --use-compress-program=zstd -cf "$$$$$$$${OUTPUT_ARCHIVE}" -C "$$$$$$$${ROOTFS_DIR}" .
|
||||
else
|
||||
$$(error Unsupported compression mode)
|
||||
endif
|
||||
|
||||
# Define global references
|
||||
$$(DISTRO_NAME)_$$(RELEASE_NAME)_RECEIPES := $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_RECEIPES) $$(RECEIPE_NAME)
|
||||
$$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DIR := $1
|
||||
$$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT := $(DIST_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/$$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs.$$(ROOTFS_COMPRESSION_SUFFIX)
|
||||
$$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT := $(DIST_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/$$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs.$$(COMPRESSION_SUFFIX)
|
||||
ROOTFS_TARGETS += $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs
|
||||
|
||||
# Populate workdir
|
||||
@@ -84,8 +87,6 @@ endif
|
||||
endef
|
||||
$$(foreach dep,$$(EXTENDS),$$(eval $$(call check_receipe_exist,$$(dep))))
|
||||
undefine check_receipe_exist
|
||||
# Directory timestamp is not reliable so always resync staging dir
|
||||
.PHONY: $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/receipes/$$(RECEIPE_NAME)
|
||||
$(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/receipes/$$(RECEIPE_NAME): $$(foreach depname,$$(EXTENDS),$$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(depname)_DIR)) $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_DIR)
|
||||
$$(dir_guard)
|
||||
rm -rf "$$@"
|
||||
@@ -96,11 +97,11 @@ $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/receipes/$$(RECEIPE_NAME): $$(fo
|
||||
.PHONY: $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs
|
||||
$$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(RECEIPE_NAME)-rootfs: $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT)
|
||||
define GENERATE_TAR_TARGET
|
||||
$$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT): $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/receipes/$$(RECEIPE_NAME)
|
||||
$$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT): | $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/receipes/$$(RECEIPE_NAME)
|
||||
$$$$(dir_guard)
|
||||
$(CONTAINER_CMD) run --rm \
|
||||
-v $(ROOT_DIR)/tools:/image-builder/tools:ro \
|
||||
-v $$$$+:/image-builder/receipe:ro \
|
||||
-v $$$$|:/image-builder/receipe:ro \
|
||||
-v $$$$(dir $$$$@):/image-builder/output \
|
||||
$(CONTAINER_IMAGE_TAG) \
|
||||
/bin/sh -c ' \
|
||||
@@ -109,7 +110,7 @@ $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(RECEIPE_NAME)_ARTIFACT): $(STAGING_DIR)/$
|
||||
./build_rootfs.sh -i /image-builder/receipe -o /tmp/rootfs -p $$(PACKAGE_MANAGER) && \
|
||||
export OUTPUT_ARCHIVE=/image-builder/output/$$$$(notdir $$$$@) && \
|
||||
export ROOTFS_DIR=/tmp/rootfs && \
|
||||
$$(ROOTFS_COMPRESSION_CMD)'
|
||||
$$(COMPRESSION_CMD)'
|
||||
endef
|
||||
$$(eval $$(GENERATE_TAR_TARGET))
|
||||
|
||||
@@ -117,9 +118,86 @@ $$(eval $$(GENERATE_TAR_TARGET))
|
||||
# Reset registers again
|
||||
undefine GENERATE_TAR_TARGET
|
||||
undefine EXTENDS
|
||||
undefine ROOTFS_COMPRESSION_CMD
|
||||
undefine ROOTFS_COMPRESSION_SUFFIX
|
||||
undefine ROOTFS_COMPRESSION
|
||||
undefine COMPRESSION_CMD
|
||||
undefine COMPRESSION_SUFFIX
|
||||
undefine COMPRESSION
|
||||
undefine RECEIPE_NAME
|
||||
|
||||
endef
|
||||
|
||||
########
|
||||
define add_device
|
||||
ifndef RELEASE_NAME
|
||||
$$(error Not within distro release section)
|
||||
endif
|
||||
ifdef DEVICE_NAME
|
||||
$$(error Nested device section is not allowed! Currently in "$$(DISTRO_NAME) $$(RELEASE_NAME) $$(DEVICE_NAME)")
|
||||
endif
|
||||
|
||||
undefine DEVICE_NAME
|
||||
|
||||
$$(eval $$(call stack_include,$1/device.mk))
|
||||
|
||||
ifndef DEVICE_NAME
|
||||
$$(error DEVICE_NAME not provided)
|
||||
endif
|
||||
|
||||
undefine DEVICE_NAME
|
||||
endef
|
||||
|
||||
|
||||
########
|
||||
define add_device_profile
|
||||
ifndef DEVICE_NAME
|
||||
$$(error Not within device section)
|
||||
endif
|
||||
ifdef PROFILE_NAME
|
||||
$$(error Nested profile section is not allowed! Currently in "$$(DISTRO_NAME) $$(RELEASE_NAME) $$(DEVICE_NAME)" $$(PROFILE_NAME))
|
||||
endif
|
||||
|
||||
undefine PROFILE_NAME
|
||||
|
||||
$$(eval $$(call stack_include,$1/profile.mk))
|
||||
|
||||
ifndef PROFILE_NAME
|
||||
$$(error PROFILE_NAME not provided)
|
||||
endif
|
||||
|
||||
BSP_PROFILE_DIR := $1
|
||||
|
||||
define GENERATE_RECEIPE_PROFILE_MATRIX
|
||||
BSP_TARGETS += $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)-$$(PROFILE_NAME)
|
||||
$$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)_PROFILES += $$(PROFILE_NAME)
|
||||
|
||||
.PHONY: $$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)-$$(PROFILE_NAME)
|
||||
$$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)-$$(PROFILE_NAME): $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/bsp/$$(PROFILE_NAME)/$$(1) $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_ARTIFACT)
|
||||
@mkdir -p $(DIST_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/$$(DEVICE_NAME)
|
||||
$(CONTAINER_CMD) run --privileged --rm \
|
||||
-v $(ROOT_DIR)/tools:/image-builder/tools:ro \
|
||||
-v $$$$<:/image-builder/receipe:ro \
|
||||
-v $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_ARTIFACT):/image-builder/$$(notdir $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_ARTIFACT)):ro \
|
||||
-v $(DIST_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/$$(DEVICE_NAME):/image-builder/output \
|
||||
$(CONTAINER_IMAGE_TAG) \
|
||||
/bin/sh -c ' set -x && \
|
||||
cd /image-builder/tools && \
|
||||
LOG_LEVEL=DEBUG ./build_bsp.sh -i /image-builder/receipe -s /image-builder/$$(notdir $$($$(DISTRO_NAME)_$$(RELEASE_NAME)_$$(1)_ARTIFACT)) -o /image-builder/output/$$(DISTRO_NAME)-$$(RELEASE_NAME)-$$(1)-$$(DEVICE_NAME)-$$(PROFILE_NAME) -p $$(PACKAGE_MANAGER)'
|
||||
|
||||
ifneq ($$$$(wildcard $$(BSP_PROFILE_DIR)/extensions/$$(1)/.),)
|
||||
# corresponding extension exists
|
||||
BSP_PROFILE_EXTENSION_DIR := $$(BSP_PROFILE_DIR)/extensions/$$(1)
|
||||
endif
|
||||
|
||||
.PHONY: $(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/bsp/$$(PROFILE_NAME)/$$(1)
|
||||
$(STAGING_DIR)/$$(DISTRO_NAME)/$$(RELEASE_NAME)/bsp/$$(PROFILE_NAME)/$$(1): $$$$(BSP_PROFILE_DIR) $$$$(BSP_PROFILE_EXTENSION_DIR)
|
||||
$$$$(dir_guard)
|
||||
rm -rf "$$@"
|
||||
@# Not preserving modification time, aka -t
|
||||
rsync -rlpgoD --exclude profile.mk --exclude extensions $$$$(foreach dep,$$$$+,$$$$(dep)/) $$$$@
|
||||
|
||||
endef
|
||||
$$(foreach receipe,$$($$(DISTRO_NAME)_$$(RELEASE_NAME)_RECEIPES),$$(eval $$(call GENERATE_RECEIPE_PROFILE_MATRIX,$$(receipe))))
|
||||
|
||||
undefine PROFILE_NAME
|
||||
undefine BSP_PROFILE_DIR
|
||||
undefine GENERATE_RECEIPE_PROFILE_MATRIX
|
||||
endef
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
RECEIPE_NAME := base
|
||||
ROOTFS_COMPRESSION := zstd
|
||||
COMPRESSION := zstd
|
||||
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
U_BOOT_PROMPT="2"
|
||||
U_BOOT_MENU_LABEL="OpenEuler GNU/Linux, kernel"
|
||||
# tty enabled on both serial0 and fbdev
|
||||
U_BOOT_PARAMETERS="rootwait rw earlycon=sbi console=tty0 console=ttyS0,115200 rd.multipath=0"
|
||||
U_BOOT_ROOT=
|
||||
U_BOOT_FDT_DIR="/dtb-"
|
||||
@@ -0,0 +1,3 @@
|
||||
DEVICE_NAME := SpacemiT-K1
|
||||
|
||||
$(foreach profile_dir,$(filter-out %.mk,$(wildcard $(CURRENT_DIR)*)),$(eval $(call add_device_profile,$(profile_dir))))
|
||||
+1
@@ -0,0 +1 @@
|
||||
linux-firmware
|
||||
+9
-8
@@ -1,23 +1,24 @@
|
||||
DISK_TABLE_TYPE=GUID
|
||||
OUTPUT_FORMAT=partitioned_disk
|
||||
PARTITION_TABLE_TYPE=GUID
|
||||
|
||||
PARTITION_1_OFFSET=1MB
|
||||
PARTITION_1_LENGTH=499MB
|
||||
PARTITION_1_SIZE=499M
|
||||
PARTITION_1_NAME="oerv-boot"
|
||||
PARTITION_1_UUID=
|
||||
PARTITION_1_TYPE=bls_boot
|
||||
PARTITION_1_ATTRS=legacy_boot
|
||||
PARTITION_1_USAGE=MOUNTPOINT
|
||||
PARTITION_1_MOUNTPONT="/boot"
|
||||
PARTITION_1_FILESYSTEM=vfat
|
||||
PARTITION_1_MOUNTPOINT="/boot"
|
||||
PARTITION_1_FS=vfat
|
||||
PARTITION_1_FS_UUID=
|
||||
|
||||
PARTITION_2_OFFSET=
|
||||
PARTITION_2_LENGTH=
|
||||
PARTITION_2_SIZE=
|
||||
PARTITION_2_NAME="oerv-root"
|
||||
PARTITION_2_UUID=
|
||||
PARTITION_2_TYPE=linux_root_riscv64
|
||||
PARTITION_2_ATTRS=
|
||||
PARTITION_2_USAGE=MOUNTPOINT
|
||||
PARTITION_2_MOUNTPONT="/"
|
||||
PARTITION_1_FILESYSTEM=ext4
|
||||
PARTITION_1_FS_UUID=
|
||||
PARTITION_2_MOUNTPOINT="/"
|
||||
PARTITION_2_FS=ext4
|
||||
PARTITION_2_FS_UUID=
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
cp 50-spacemit_k1_fw.conf "${ROOTFS_DIR}/etc/dracut.conf.d/"
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
cat << EOF | column -t | tee "${ROOTFS_DIR}/etc/fstab"
|
||||
UUID=$($get_fs_uuid_by_mountpoint /) / ext4 errors=remount-ro 0 1
|
||||
UUID=$($get_fs_uuid_by_mountpoint /boot) /boot vfat defaults 0 2
|
||||
EOF
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
. "${ROOTFS_DIR}/etc/os-release"
|
||||
|
||||
cat << EOF | tee "${ROOTFS_DIR}/etc/default/u-boot"
|
||||
U_BOOT_PROMPT="2"
|
||||
U_BOOT_MENU_LABEL="${PRETTY_NAME}"
|
||||
# tty enabled on both serial0 and fbdev
|
||||
U_BOOT_PARAMETERS="rootwait rw earlycon=sbi console=tty0 console=ttyS0,115200 rd.multipath=0"
|
||||
U_BOOT_ROOT=$($get_fs_uuid_by_mountpoint /)
|
||||
U_BOOT_FDT_DIR="/dtb-"
|
||||
EOF
|
||||
@@ -0,0 +1 @@
|
||||
PROFILE_NAME := extlinux
|
||||
@@ -1,3 +1,4 @@
|
||||
RELEASE_NAME := 24.03-LTS-SP2
|
||||
|
||||
$(foreach receipe_dir,$(filter-out %.mk,$(wildcard $(CURRENT_DIR)userspace/*)),$(eval $(call add_receipe,$(receipe_dir))))
|
||||
$(foreach device_dir,$(filter-out %.mk,$(wildcard $(CURRENT_DIR)bsp/*)),$(eval $(call add_device,$(device_dir))))
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
RECEIPE_NAME := base
|
||||
ROOTFS_COMPRESSION := zstd
|
||||
COMPRESSION := zstd
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
RECEIPE_NAME := xfce4
|
||||
ROOTFS_COMPRESSION := zstd
|
||||
COMPRESSION := zstd
|
||||
EXTENDS := base
|
||||
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck shell=dash disable=SC2317
|
||||
# Unreachable Detection is disabled as the script relies on indirect call.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
|
||||
. ./logging.sh
|
||||
|
||||
RECEIPE_DIR=""
|
||||
ROOTFS_ARCHIVE=""
|
||||
PACKAGE_MANAGER=""
|
||||
OUTPUT_PREFIX=""
|
||||
|
||||
ROOTFS_DIR=""
|
||||
|
||||
. ./receipe_helper.sh
|
||||
. ./fs_helper/vfat.sh
|
||||
. ./fs_helper/ext4.sh
|
||||
. ./partition_table_helper/guid.sh
|
||||
. ./image_layout_helper.sh
|
||||
. ./image_creation_helper.sh
|
||||
|
||||
parse_image_layout() {
|
||||
logi "Parsing image layout"
|
||||
|
||||
# Introduce subshell for isolated env vars
|
||||
image_layout_info="$(parse_image_layout_impl)"
|
||||
logdraw "${image_layout_info}"
|
||||
}
|
||||
|
||||
create_image() {
|
||||
logi "Creating image"
|
||||
(eval "${image_layout_info}" && create_image_impl)
|
||||
}
|
||||
|
||||
generate_bsp() {
|
||||
# Pre-process image layout for subsequent post-install scripts
|
||||
parse_image_layout
|
||||
|
||||
# Prepare pre-built rootfs
|
||||
ROOTFS_DIR="$(mktemp -d)"
|
||||
logi "Extracting pre-built rootfs to ${ROOTFS_DIR}"
|
||||
tar -xf "${ROOTFS_ARCHIVE}" -C "${ROOTFS_DIR}"
|
||||
|
||||
setup_repo
|
||||
|
||||
SCRIPT_ENV_SETUP_CMD="
|
||||
export ROOTFS_DIR=${ROOTFS_DIR} &&
|
||||
$(echo "${image_layout_info}" | sed -E 's/^(.+)$/export \1 \&\& /')
|
||||
export get_fs_uuid_by_mountpoint='${get_fs_uuid_by_mountpoint}' &&
|
||||
"
|
||||
install_packages "${SCRIPT_ENV_SETUP_CMD}"
|
||||
post_scripts "${SCRIPT_ENV_SETUP_CMD}"
|
||||
create_image
|
||||
|
||||
# Clean up
|
||||
rm -rf "${ROOTFS_DIR}"
|
||||
}
|
||||
|
||||
print_usage() {
|
||||
# Keep help message within 80 cols for special consoles.
|
||||
cat << EOF
|
||||
|
||||
Usage: $0 [-hp] [-i input [-i input [...]]] output
|
||||
-h Print this help message.
|
||||
-s rootfs Path to pre-built rootfs archive
|
||||
-i receipe Path to BSP receipe directory
|
||||
-p package_manager
|
||||
Specify which package manager should be
|
||||
used.
|
||||
-o output Prefix for generated files
|
||||
Environment Variables:
|
||||
LOG_LEVEL Controls the log level of this script.
|
||||
One of: DEBUG, INFO, WARN, ERROR
|
||||
Defaults to: INFO
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
# Handling args
|
||||
while getopts "i:o:p:s:h" o; do
|
||||
case "${o}" in
|
||||
h)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
i)
|
||||
RECEIPE_DIR=${OPTARG}
|
||||
;;
|
||||
s)
|
||||
ROOTFS_ARCHIVE=${OPTARG}
|
||||
;;
|
||||
p)
|
||||
PACKAGE_MANAGER=${OPTARG}
|
||||
;;
|
||||
o)
|
||||
OUTPUT_PREFIX=${OPTARG}
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
logi "BSP Builder"
|
||||
|
||||
# Validate inputs
|
||||
if [ -z "${RECEIPE_DIR}" ]; then
|
||||
loge "No receipe is specified!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${ROOTFS_ARCHIVE}" ]; then
|
||||
loge "No output dir is specified!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${OUTPUT_PREFIX}" ]; then
|
||||
loge "No output dir is specified!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${PACKAGE_MANAGER}" ]; then
|
||||
loge "No package manager is specified!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
logi "Using receipe: ${RECEIPE_DIR}"
|
||||
logi "- ROOTFS_ARCHIVE: ${ROOTFS_ARCHIVE}"
|
||||
logi "- PACKAGE_MANAGER: ${PACKAGE_MANAGER}"
|
||||
logi "- OUTPUT_PREFIX: ${OUTPUT_PREFIX}"
|
||||
|
||||
generate_bsp
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
+11
-117
@@ -11,125 +11,15 @@ RECEIPE_DIR=""
|
||||
ROOTFS_DIR=""
|
||||
PACKAGE_MANAGER=""
|
||||
|
||||
|
||||
is_function() {
|
||||
type "$1" 2>/dev/null | head -n 1 | grep 'function' > /dev/null
|
||||
}
|
||||
|
||||
setup_repo_yum() {
|
||||
mkdir -p "${ROOTFS_DIR}/etc/yum.repos.d"
|
||||
cp "${RECEIPE_DIR}"/repos.d/* "${ROOTFS_DIR}/etc/yum.repos.d"
|
||||
}
|
||||
|
||||
setup_repo() {
|
||||
logi "Preconfiguring package repo..."
|
||||
setup_repo_func="setup_repo_${PACKAGE_MANAGER}"
|
||||
if ! is_function "${setup_repo_func}" ; then
|
||||
loge "Package manager ${PACKAGE_MANAGER} not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"setup_repo_${PACKAGE_MANAGER}"
|
||||
}
|
||||
|
||||
execute_script_dir() {
|
||||
script_dir="$1"
|
||||
|
||||
find "${script_dir}" -maxdepth 1 -mindepth 1 -type d,l | sort | \
|
||||
while IFS= read -r line; do
|
||||
logi "Executing scripts: ${line}"
|
||||
bash -c "
|
||||
cd ${line} &&
|
||||
export ROOTFS_DIR=${ROOTFS_DIR} &&
|
||||
${line}/entry.sh
|
||||
"
|
||||
done
|
||||
}
|
||||
|
||||
install_package_cleanup_yum() {
|
||||
yum --forcearch riscv64 --installroot="${ROOTFS_DIR}" clean all
|
||||
}
|
||||
|
||||
install_package_cleanup() {
|
||||
logi "Cleanup package installation"
|
||||
install_package_cleanup_func="install_package_cleanup_${PACKAGE_MANAGER}"
|
||||
if ! is_function "${install_package_cleanup_func}" ; then
|
||||
loge "Package manager ${PACKAGE_MANAGER} not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"install_package_cleanup_${PACKAGE_MANAGER}"
|
||||
}
|
||||
|
||||
install_package_list_yum() {
|
||||
# shellcheck shell=dash disable=SC2086
|
||||
yum --forcearch riscv64 --installroot="${ROOTFS_DIR}" -y install $1
|
||||
}
|
||||
|
||||
install_package_list() {
|
||||
logi "Installing package list: $1"
|
||||
install_package_list_func="install_package_list_${PACKAGE_MANAGER}"
|
||||
if ! is_function "${install_package_list_func}" ; then
|
||||
loge "Package manager ${PACKAGE_MANAGER} not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"install_package_list_${PACKAGE_MANAGER}" "$(tr '\n' ' ' < "$1")"
|
||||
}
|
||||
|
||||
install_package_group_yum() {
|
||||
# shellcheck shell=dash disable=SC2086
|
||||
yum --forcearch riscv64 --installroot="${ROOTFS_DIR}" -y groupinstall $1
|
||||
}
|
||||
|
||||
install_package_group() {
|
||||
logi "Installing package group: $1"
|
||||
install_package_group_func="install_package_group_${PACKAGE_MANAGER}"
|
||||
if ! is_function "${install_package_group_func}" ; then
|
||||
loge "Package manager ${PACKAGE_MANAGER} not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"install_package_group_${PACKAGE_MANAGER}" "$(tr '\n' ' ' < "$1")"
|
||||
}
|
||||
|
||||
install_packages() {
|
||||
logi "Install packages..."
|
||||
find "${RECEIPE_DIR}"/packages.d/ -maxdepth 1 -mindepth 1 -type f,d,l | sort | \
|
||||
while IFS= read -r line; do
|
||||
actualpath="$(readlink -f "${line}")"
|
||||
if [ -d "${actualpath}" ]; then
|
||||
if [ -f "${line}/packages.list" ]; then
|
||||
install_package_list "${line}/packages.list"
|
||||
elif [ -f "${line}/packages.group" ]; then
|
||||
install_package_group "${line}/packages.group"
|
||||
else
|
||||
logw "No package list, ignoring ${line}"
|
||||
continue
|
||||
fi
|
||||
if [ -d "${line}/post.d" ]; then
|
||||
execute_script_dir "${line}/post.d"
|
||||
fi
|
||||
elif [ -f "${actualpath}" ]; then
|
||||
if echo "${line}" | grep ".*.list" > /dev/null; then
|
||||
install_package_list "${line}"
|
||||
elif echo "${line}" | grep ".*.group" > /dev/null; then
|
||||
install_package_group "${line}"
|
||||
else
|
||||
logw "Unsupported package list, ignoring ${line}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
install_package_cleanup
|
||||
}
|
||||
|
||||
post_scripts() {
|
||||
if [ -d "$(readlink -f "${RECEIPE_DIR}/post.d")" ]; then
|
||||
logi "Post configuring..."
|
||||
execute_script_dir "${RECEIPE_DIR}/post.d"
|
||||
fi
|
||||
}
|
||||
. ./receipe_helper.sh
|
||||
|
||||
generate_rootfs() {
|
||||
SCRIPT_ENV_SETUP_CMD="
|
||||
export ROOTFS_DIR=${ROOTFS_DIR} &&
|
||||
"
|
||||
setup_repo
|
||||
install_packages
|
||||
post_scripts
|
||||
install_packages "${SCRIPT_ENV_SETUP_CMD}"
|
||||
post_scripts "${SCRIPT_ENV_SETUP_CMD}"
|
||||
}
|
||||
|
||||
print_usage() {
|
||||
@@ -176,7 +66,7 @@ main() {
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
logi "ImageBuilder"
|
||||
logi "RootFS Builder"
|
||||
|
||||
# Validate inputs
|
||||
if [ -z "${RECEIPE_DIR}" ]; then
|
||||
@@ -187,6 +77,10 @@ main() {
|
||||
loge "No output dir is specified!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${PACKAGE_MANAGER}" ]; then
|
||||
loge "No package manager is specified!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
logi "Using receipe: ${RECEIPE_DIR}"
|
||||
logi "- ROOTFS_DIR: ${ROOTFS_DIR}"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env false
|
||||
|
||||
filesystem_generate_uuid_ext4() {
|
||||
uuidgen
|
||||
}
|
||||
|
||||
filesystem_validate_uuid_ext4() {
|
||||
echo "${1}" | sed -n '/^[0-9a-fA-F]\{8\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{12\}$/!q1'
|
||||
}
|
||||
|
||||
filesystem_set_uuid_ext4() {
|
||||
device="${1}"
|
||||
uuid="${2}"
|
||||
if ! filesystem_validate_uuid_vfat "${uuid}"; then
|
||||
loge "Invalid vfat serial number: ${uuid}"
|
||||
exit 1
|
||||
fi
|
||||
tune2fs -U "${uuid}" "${device}"
|
||||
}
|
||||
|
||||
filesystem_make_fs_ext4() {
|
||||
mkfs.ext4 "${1}"
|
||||
}
|
||||
|
||||
filesystem_shrink_ext4() {
|
||||
e2fsck -y -f "${1}"
|
||||
for i in $(seq 1 10); do resize2fs -M "${1}"; done
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env false
|
||||
|
||||
filesystem_generate_uuid_vfat() {
|
||||
hexdump -vn4 -e'1/2 "%04X" 1 "-" 1/2 "%04X" 1 "\n"' /dev/urandom
|
||||
}
|
||||
|
||||
filesystem_validate_uuid_vfat() {
|
||||
echo "${1}" | sed -n '/^[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}$/!q1'
|
||||
}
|
||||
|
||||
filesystem_set_uuid_vfat() {
|
||||
device="${1}"
|
||||
uuid="${2}"
|
||||
if ! filesystem_validate_uuid_vfat "${uuid}"; then
|
||||
loge "Invalid vfat serial number: ${uuid}"
|
||||
exit 1
|
||||
fi
|
||||
mlabel -N "$(echo "${uuid}" | tr -d '-')" -i "${device}"
|
||||
}
|
||||
|
||||
filesystem_make_fs_vfat() {
|
||||
mkfs.vfat "${1}"
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
. ./image_helper/partitioned_disk.sh
|
||||
|
||||
prepare_fs_blocks() {
|
||||
for fs_idx in ${MOUNTPOINT_SORTED_IDX}; do
|
||||
fs_mountpoint="FILESYSTEM_${fs_idx}_MOUNTPOINT"
|
||||
fs_mountpoint="${!fs_mountpoint}"
|
||||
fs_format="FILESYSTEM_${fs_idx}_FORMAT"
|
||||
fs_format="${!fs_format}"
|
||||
fs_size="FILESYSTEM_${fs_idx}_CONTAINER_SIZE"
|
||||
fs_size="${!fs_size}"
|
||||
|
||||
if [ "${fs_size}" -eq 0 ]; then
|
||||
# Flex-size partition
|
||||
# Allocating block file based on real disk usage
|
||||
real_usage_size="$(du -b -s "${ROOTFS_DIR}${fs_mountpoint}" | cut -f 1)"
|
||||
# Round-up at least 512 MB
|
||||
fs_size="$(( ((real_usage_size + 512 * 1024 * 1024) / 1024 / 1024 / 1024 + 1) * 1024 * 1024 * 1024))"
|
||||
logi "Allocating ${fs_size}B for flex-size mountpoint \"${fs_mountpoint}\""
|
||||
else
|
||||
# Make sure real usage does not exceed constraint
|
||||
real_usage_size="$(du -b -s "${ROOTFS_DIR}${fs_mountpoint}" | cut -f 1)"
|
||||
if [ "${real_usage_size}" -gt "${fs_size}" ]; then
|
||||
loge "Filesystem usage (${real_usage_size}B) exceeds limitation (${fs_size}B)"
|
||||
exit 1
|
||||
fi
|
||||
logi "Allocating ${fs_size}B for mountpoint \"${fs_mountpoint}\""
|
||||
fi
|
||||
fs_content="${FS_IMG_DIR}/$(echo "${fs_mountpoint}" | tr '/' ':').${fs_format}"
|
||||
eval "FILESYSTEM_${fs_idx}_CONTENT=${fs_content}"
|
||||
truncate -s "${fs_size}" "${fs_content}"
|
||||
"filesystem_make_fs_${fs_format}" "${fs_content}"
|
||||
|
||||
logi "Mounting \"${fs_mountpoint}\" at \"${ROOTFS_MNT}${fs_mountpoint}\""
|
||||
mkdir -p "${ROOTFS_MNT}${fs_mountpoint}"
|
||||
mount "${fs_content}" "${ROOTFS_MNT}${fs_mountpoint}"
|
||||
done
|
||||
}
|
||||
|
||||
post_fs_blocks() {
|
||||
for fs_idx in $(echo "${MOUNTPOINT_SORTED_IDX}" | rev); do
|
||||
fs_mountpoint="FILESYSTEM_${fs_idx}_MOUNTPOINT"
|
||||
fs_mountpoint="${!fs_mountpoint}"
|
||||
logi "Unmounting \"${fs_mountpoint}\" at \"${ROOTFS_MNT}${fs_mountpoint}\""
|
||||
umount "${ROOTFS_MNT}${fs_mountpoint}"
|
||||
|
||||
# Shrink filesystem if flex-size
|
||||
fs_size="FILESYSTEM_${fs_idx}_CONTAINER_SIZE"
|
||||
fs_size="${!fs_size}"
|
||||
fs_format="FILESYSTEM_${fs_idx}_FORMAT"
|
||||
fs_format="${!fs_format}"
|
||||
if [ "${fs_size}" -eq 0 ]; then
|
||||
if ! is_function "filesystem_shrink_${fs_format}" ; then
|
||||
loge "Shrinking ${fs_format} is not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
fs_content="FILESYSTEM_${fs_idx}_CONTENT"
|
||||
fs_content="${!fs_content}"
|
||||
"filesystem_shrink_${fs_format}" "${fs_content}"
|
||||
shrinked_size="$(du --apparent-size -b -s "${fs_content}" | cut -f 1)"
|
||||
logi "Shrinking filesystem mounted at \"${fs_mountpoint}\" to ${shrinked_size}B"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
create_fs_mountpoint_content() {
|
||||
ROOTFS_MNT="${WORK_DIR}/mnt"
|
||||
FS_IMG_DIR="${WORK_DIR}/content/fs"
|
||||
|
||||
mkdir -p "${ROOTFS_MNT}"
|
||||
mkdir -p "${FS_IMG_DIR}"
|
||||
|
||||
# Create and mount the filesystem block
|
||||
prepare_fs_blocks
|
||||
# Restore plain rootfs onto structured mountpoint
|
||||
logi "Copy files"
|
||||
rsync -ah "${ROOTFS_DIR}/" "${ROOTFS_MNT}"
|
||||
# Umount and shrink (if necessary)
|
||||
post_fs_blocks
|
||||
|
||||
rm -rf "${ROOTFS_MNT}"
|
||||
}
|
||||
|
||||
create_image_impl() {
|
||||
if ! is_function "create_image_impl_${OUTPUT_FORMAT}"; then
|
||||
loge "Image type \"${OUTPUT_FORMAT}\" not implemented"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WORK_DIR="$(mktemp -d)"
|
||||
|
||||
# Dealing with fs mountpoint separately as it may operate over multiple segments
|
||||
create_fs_mountpoint_content
|
||||
|
||||
"create_image_impl_${OUTPUT_FORMAT}"
|
||||
|
||||
rm -rf "${WORK_DIR}"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env false
|
||||
|
||||
# A partitioned disk configuration must describe:
|
||||
# - PARTITION_TABLE_TYPE
|
||||
# - PARTITION_x_USAGE
|
||||
|
||||
match_partition_content_MOUNTPOINT() {
|
||||
fs_idx="PARTITION_${part_idx}_FILESYSTEM_IDX"
|
||||
fs_idx="${!fs_idx}"
|
||||
fs_content="FILESYSTEM_${fs_idx}_CONTENT"
|
||||
fs_content="${!fs_content}"
|
||||
eval "PARTITION_${part_idx}_CONTENT=${fs_content}"
|
||||
}
|
||||
|
||||
prepare_partition_content() {
|
||||
for part_idx in $(seq 1 99); do
|
||||
if eval "[ -z \"\${PARTITION_${part_idx}_USAGE+x}\" ]"; then
|
||||
break
|
||||
fi
|
||||
part_usage="PARTITION_${part_idx}_USAGE"
|
||||
part_usage="${!part_usage}"
|
||||
|
||||
if ! is_function "match_partition_content_${part_usage}"; then
|
||||
loge "Content matching for partition usage \"${part_usage}\" not implemented"
|
||||
exit 1
|
||||
fi
|
||||
"match_partition_content_${part_usage}"
|
||||
|
||||
done
|
||||
}
|
||||
|
||||
create_image_impl_partitioned_disk() {
|
||||
logi "Creating partitioned_disk image"
|
||||
|
||||
prepare_partition_content
|
||||
|
||||
disk_part_table="${PARTITION_TABLE_TYPE}"
|
||||
if ! is_function "produce_image_${disk_part_table}" ; then
|
||||
loge "Partition table ${disk_part_table} is not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"produce_image_${disk_part_table}"
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env false
|
||||
|
||||
parse_image_layout_impl_output_format_partitioned_disk() {
|
||||
logi "Parsing partitioned_disk image"
|
||||
if [ -z ${PARTITION_TABLE_TYPE+x} ]; then
|
||||
loge "PARTITION_TABLE_TYPE not provided"
|
||||
exit 1
|
||||
fi
|
||||
echo "PARTITION_TABLE_TYPE=${PARTITION_TABLE_TYPE}"
|
||||
if ! is_function "parse_image_layout_impl_partitioned_disk_table_${PARTITION_TABLE_TYPE}"; then
|
||||
loge "PARTITION_TABLE_TYPE \"${PARTITION_TABLE_TYPE}\" not implemented"
|
||||
exit 1
|
||||
fi
|
||||
"parse_image_layout_impl_partitioned_disk_table_${PARTITION_TABLE_TYPE}"
|
||||
}
|
||||
|
||||
parse_image_layout_impl_sort_mountpoint() {
|
||||
mountpoints=""
|
||||
for fs_idx in $(seq 0 $(( IMAGE_LAYOUT_FILESYSTEM_COUNT - 1 ))); do
|
||||
mountpoints+="$(eval echo \$\{FILESYSTEM_"${fs_idx}"_MOUNTPOINT\}) ${fs_idx}
|
||||
"
|
||||
done
|
||||
mountpoints="$(echo "${mountpoints}" | sort)"
|
||||
sorted_mountpoint_idx="$(echo "${mountpoints}" | rev | cut -d ' ' -f 1 | rev | tr '\n' ' ')"
|
||||
echo "MOUNTPOINT_SORTED_IDX=\"${sorted_mountpoint_idx}\""
|
||||
}
|
||||
|
||||
parse_image_layout_impl() {
|
||||
# shellcheck shell=dash disable=SC1091
|
||||
. "${RECEIPE_DIR}/image-layout.conf"
|
||||
|
||||
if [ -z ${OUTPUT_FORMAT+x} ]; then
|
||||
loge "OUTPUT_FORMAT not provided"
|
||||
exit 1
|
||||
fi
|
||||
echo "OUTPUT_FORMAT=${OUTPUT_FORMAT}"
|
||||
if ! is_function "parse_image_layout_impl_output_format_${OUTPUT_FORMAT}"; then
|
||||
loge "OUTPUT_FORMAT \"${OUTPUT_FORMAT}\" not implemented"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Collect number of FILESYSTEMs
|
||||
IMAGE_LAYOUT_FILESYSTEM_COUNT=0
|
||||
|
||||
"parse_image_layout_impl_output_format_${OUTPUT_FORMAT}"
|
||||
|
||||
parse_image_layout_impl_sort_mountpoint
|
||||
}
|
||||
|
||||
# shellcheck shell=dash disable=SC2016
|
||||
get_fs_uuid_by_mountpoint_impl='
|
||||
get_fs_uuid_by_mountpoint_impl() {
|
||||
for part_idx in $(seq 1 99); do
|
||||
if eval "[ -z \"\${PARTITION_${part_idx}_USAGE+x}\" ]"; then
|
||||
echo "partition not found by mountpoint: ${1} 1>&2";
|
||||
exit 1;
|
||||
fi;
|
||||
fs_idx="PARTITION_${part_idx}_FILESYSTEM_IDX" &&
|
||||
fs_idx="${!fs_idx}" &&
|
||||
fs_mp="FILESYSTEM_${fs_idx}_MOUNTPOINT" &&
|
||||
fs_mp="${!fs_mp}" &&
|
||||
if [ "${fs_mp}" = "${1}" ]; then
|
||||
fs_uuid="FILESYSTEM_${fs_idx}_UUID" &&
|
||||
echo "${!fs_uuid}" &&
|
||||
return;
|
||||
fi;
|
||||
done
|
||||
;}; get_fs_uuid_by_mountpoint_impl'
|
||||
|
||||
get_fs_uuid_by_mountpoint="eval ${get_fs_uuid_by_mountpoint_impl}"
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
#!/usr/bin/env dash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
|
||||
. ./logging.sh
|
||||
|
||||
INPUT_FILES=""
|
||||
OUTPUT_FILE=""
|
||||
ALIGNMENT_SECTOR_SIZE=""
|
||||
ALIGNMENT_SECTOR_COUNT=""
|
||||
ALIGNMENT_BYTES=""
|
||||
|
||||
calc_parts_total_size() {
|
||||
local total_aligned_blocks=0
|
||||
while IFS= read -r line; do
|
||||
if [ -z "${line}" ]; then
|
||||
continue
|
||||
fi
|
||||
ifile_aligned_blocks="$(du --apparent-size -B ${ALIGNMENT_BYTES} "${line}" | cut -f 1)"
|
||||
logi "Input: ${ifile_aligned_blocks} blocks: ${line}"
|
||||
total_aligned_blocks="$((total_aligned_blocks+ifile_aligned_blocks))"
|
||||
done << EOF
|
||||
$INPUT_FILES
|
||||
EOF
|
||||
echo "${total_aligned_blocks}"
|
||||
}
|
||||
|
||||
probe_alignment() {
|
||||
local TEMP_FILE
|
||||
TEMP_FILE="$(mktemp)"
|
||||
truncate -s 1G "${TEMP_FILE}"
|
||||
ALIGNMENT_SECTOR_SIZE="$(sgdisk -p "${TEMP_FILE}" | sed -rn 's/Sector size \(logical\): ([0-9]+) bytes/\1/p')"
|
||||
ALIGNMENT_SECTOR_COUNT="$(sgdisk -p "${TEMP_FILE}" | sed -rn 's/Partitions will be aligned on ([0-9]+)-sector boundaries/\1/p')"
|
||||
ALIGNMENT_BYTES="$((ALIGNMENT_SECTOR_SIZE*ALIGNMENT_SECTOR_COUNT))"
|
||||
rm "${TEMP_FILE}"
|
||||
logd "Probed alignment: ${ALIGNMENT_BYTES}B (${ALIGNMENT_SECTOR_SIZE}B*${ALIGNMENT_SECTOR_COUNT})"
|
||||
}
|
||||
|
||||
print_usage() {
|
||||
# Keep help message within 80 cols for special consoles.
|
||||
cat << EOF
|
||||
Concatenate multiple partitions into a single GUID disk image.
|
||||
This script only handles the image creation.
|
||||
Usage: $0 [-hp] [-i input [-i input [...]]] output
|
||||
-h Print this help message.
|
||||
-p Print the alignment, in bytes
|
||||
-i input Partition images to be included.
|
||||
Multiple inputs are arranged as the specified order.
|
||||
It is recommended to have input file size rounded according
|
||||
to the alignment requirements, as the partition will always
|
||||
be placed at alignment boundaries.
|
||||
output The produced disk image.
|
||||
Environment Variables:
|
||||
LOG_LEVEL Controls the log level of this script.
|
||||
One of: DEBUG, INFO, WARN, ERROR
|
||||
Defaults to: INFO
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
# Handling args
|
||||
while getopts "i:hp" o; do
|
||||
case "${o}" in
|
||||
h)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
i)
|
||||
INPUT_FILES="${INPUT_FILES}${OPTARG}
|
||||
"
|
||||
;;
|
||||
p)
|
||||
probe_alignment
|
||||
echo -n "${ALIGNMENT_BYTES}"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
OUTPUT_FILE="${1:-}"
|
||||
|
||||
# Validate inputs
|
||||
if [ -z "${OUTPUT_FILE}" ]; then
|
||||
loge "No output file is specified!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${INPUT_FILES}" ]; then
|
||||
loge "No input file is specified!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
probe_alignment
|
||||
logi "Using alignment: ${ALIGNMENT_SECTOR_COUNT} sectors @ ${ALIGNMENT_SECTOR_SIZE}B"
|
||||
|
||||
local target_image_content_size
|
||||
target_image_content_size="$(calc_parts_total_size)"
|
||||
|
||||
# One block is reserved at both beginning and ending, for GPT tables.
|
||||
# Final image size will be target_image_content_size+2 blocks
|
||||
local final_image_blocks="$((target_image_content_size+2))"
|
||||
local final_image_size_b="$((final_image_blocks*ALIGNMENT_BYTES))"
|
||||
logi "Allocating output image (${final_image_blocks} blocks, ${final_image_size_b}B) at ${OUTPUT_FILE}"
|
||||
truncate -s "${final_image_size_b}" "${OUTPUT_FILE}"
|
||||
|
||||
logi "Writing GUID Partition Table"
|
||||
1>/dev/null sgdisk -Z "${OUTPUT_FILE}"
|
||||
1>/dev/null sgdisk -G "${OUTPUT_FILE}"
|
||||
|
||||
local curr_part_idx
|
||||
curr_part_idx=0
|
||||
local curr_part_start_sector
|
||||
curr_part_start_sector="${ALIGNMENT_SECTOR_COUNT}"
|
||||
while IFS= read -r line; do
|
||||
if [ -z "${line}" ]; then
|
||||
continue
|
||||
fi
|
||||
curr_part_idx="$((curr_part_idx+1))"
|
||||
local curr_part_blocks
|
||||
curr_part_blocks="$(du --apparent-size -B "${ALIGNMENT_BYTES}" "${line}" | cut -f 1)"
|
||||
local curr_part_sectors="$((curr_part_blocks*ALIGNMENT_BYTES/ALIGNMENT_SECTOR_SIZE))"
|
||||
logi "Create partition ${curr_part_idx}: ${curr_part_sectors} sectors @ ${curr_part_start_sector} sector"
|
||||
1>/dev/null sgdisk --new "${curr_part_idx}:${curr_part_start_sector}:+${curr_part_sectors}" "${OUTPUT_FILE}"
|
||||
logi "Copy contents to part ${curr_part_idx} from ${line}"
|
||||
2>/dev/null dd if="${line}" of="${OUTPUT_FILE}" bs="${ALIGNMENT_SECTOR_SIZE}" seek="${curr_part_start_sector}" count="${curr_part_sectors}" conv=notrunc iflag=fullblock
|
||||
curr_part_start_sector="$((curr_part_start_sector+curr_part_sectors))"
|
||||
done << EOF
|
||||
$INPUT_FILES
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env dash
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck shell=dash disable=SC2034
|
||||
# TODO: dynamically generate help message
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
@@ -78,12 +79,12 @@ handle_set_uuid() {
|
||||
loge "part_id not specified."
|
||||
exit 2
|
||||
fi
|
||||
local partid; partid="$1"; shift 1
|
||||
local new_uuid; new_uuid="${1:-}"
|
||||
partid="$1"; shift 1
|
||||
new_uuid="${1:-}"
|
||||
if [ -z "${new_uuid}" ]; then
|
||||
new_uuid="$(uuidgen)"
|
||||
fi
|
||||
logd "Setting new UUID to part ${partid}: ${new_uuid}"
|
||||
logd "Setting new UUID for part ${partid}: ${new_uuid}"
|
||||
1>/dev/null sgdisk -u "${partid}:${new_uuid}" "${TARGET_FILE}"
|
||||
}
|
||||
|
||||
@@ -92,26 +93,25 @@ handle_set_type() {
|
||||
loge "part_id not specified."
|
||||
exit 2
|
||||
fi
|
||||
local partid; partid="$1"; shift 1
|
||||
partid="$1"; shift 1
|
||||
if [ $# -eq 0 ]; then
|
||||
loge "Type not specified."
|
||||
exit 2
|
||||
fi
|
||||
local parttype; parttype="$1"; shift 1
|
||||
parttype="$1"; shift 1
|
||||
|
||||
if ! printf '%s' "${TYPENAME}" | grep -E "^${parttype}$" > /dev/null; then
|
||||
loge "Unsupported type: ${parttype}"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
local typecode
|
||||
typecode="$(getvarbyname "TYPECODE_$(str_to_upper "${parttype}")")"
|
||||
|
||||
local supported_attrs=""
|
||||
supported_attrs=""
|
||||
supported_attrs="$(getvarbyname "TYPECODE_$(str_to_upper "${parttype}")_ATTRS:-")"
|
||||
local typeattrbits=""
|
||||
typeattrbits=""
|
||||
while [ $# -ne 0 ]; do
|
||||
local curr_attr="$1"
|
||||
curr_attr="$1"
|
||||
shift 1
|
||||
if ! printf '%s' "${supported_attrs}" | grep -E "^${curr_attr}$" > /dev/null; then
|
||||
loge "Usupported attribute for type ${parttype}: ${curr_attr}"
|
||||
@@ -120,13 +120,13 @@ handle_set_type() {
|
||||
typeattrbits="${typeattrbits}$(getvarbyname "TYPECODE_$(str_to_upper "${parttype}")_ATTRS_$(str_to_upper "${curr_attr}")")
|
||||
"
|
||||
done
|
||||
logd "Set type code to ${typecode} for part ${partid}"
|
||||
logd "Set type code for part ${partid}: ${typecode}"
|
||||
1>/dev/null sgdisk -t "${partid}:${typecode}" "${TARGET_FILE}"
|
||||
printf '%s' "${typeattrbits}" | while read -r attrbit ; do
|
||||
if [ -z "${attrbit}" ]; then
|
||||
continue
|
||||
fi
|
||||
logd "Set partition attribute bit ${attrbit} for part ${partid}"
|
||||
logd "Set partition attribute bit for part ${partid}: ${attrbit}"
|
||||
1>/dev/null sgdisk -A "${partid}:set:${attrbit}" "${TARGET_FILE}"
|
||||
done
|
||||
}
|
||||
@@ -136,13 +136,13 @@ handle_set_name() {
|
||||
loge "part_id not specified."
|
||||
exit 2
|
||||
fi
|
||||
local partid; partid="$1"; shift 1
|
||||
partid="$1"; shift 1
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
loge "part name not specified."
|
||||
exit 2
|
||||
fi
|
||||
local partname; partname="$1"; shift 1
|
||||
partname="$1"; shift 1
|
||||
1>/dev/null sgdisk -c "${partid}:${partname}" "${TARGET_FILE}"
|
||||
}
|
||||
|
||||
@@ -229,7 +229,6 @@ main() {
|
||||
TARGET_FILE="$1"
|
||||
shift 1
|
||||
|
||||
local arg_command
|
||||
if [ "$#" -eq 0 ]; then
|
||||
loge "No command specified."
|
||||
exit 1
|
||||
@@ -0,0 +1,206 @@
|
||||
# Assuming sector size is 512B
|
||||
readonly GUID_TABLE_SECTOR_SIZE=512
|
||||
# Default alignment of the offset of each partition
|
||||
readonly GUID_TABLE_ALIGNMENT="$(( 2048 * GUID_TABLE_SECTOR_SIZE ))"
|
||||
# Reserved size for partition table header
|
||||
readonly GUID_TABLE_RESV_SIZE="$(( 34 * GUID_TABLE_SECTOR_SIZE ))"
|
||||
|
||||
parse_image_layout_impl_partitioned_disk_table_GUID_part_usage_MOUNTPOINT() {
|
||||
logi "Parsing mountpoint usage"
|
||||
|
||||
# PARTITION_xx_FS
|
||||
part_fs="$(eval echo \$\{PARTITION_"${part_idx}"_FS:-\})"
|
||||
if ! is_function "filesystem_validate_uuid_${part_fs}"; then
|
||||
loge "File system \"${part_fs}\" not implemented"
|
||||
exit 1
|
||||
fi
|
||||
echo "FILESYSTEM_${IMAGE_LAYOUT_FILESYSTEM_COUNT}_FORMAT=${part_fs}"
|
||||
|
||||
# PARTITION_xx_FS_UUID
|
||||
part_fs_uuid="$(eval echo \$\{PARTITION_"${part_idx}"_FS_UUID:-\})"
|
||||
if [ -n "${part_fs_uuid}" ]; then
|
||||
if ! "filesystem_validate_uuid_${part_fs}" "${part_fs_uuid}"; then
|
||||
loge "Inavlid ${part_fs} UUID: \"${part_fs_uuid}\""
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ -z "${part_fs_uuid}" ]; then
|
||||
part_fs_uuid="$("filesystem_generate_uuid_${part_fs}")"
|
||||
fi
|
||||
echo "FILESYSTEM_${IMAGE_LAYOUT_FILESYSTEM_COUNT}_UUID=${part_fs_uuid}"
|
||||
|
||||
# PARTITION_xx_MOUNTPOINT
|
||||
part_mountpoint="$(eval echo \$\{PARTITION_"${part_idx}"_MOUNTPOINT:-\})"
|
||||
if ! case "${part_mountpoint}" in (/*) pathchk -- "${part_mountpoint}";; (*) ! : ;; esac; then
|
||||
loge "Invalid mountpoint: ${part_mountpoint}"
|
||||
exit 1
|
||||
fi
|
||||
echo "FILESYSTEM_${IMAGE_LAYOUT_FILESYSTEM_COUNT}_MOUNTPOINT=${part_mountpoint}"
|
||||
eval "FILESYSTEM_${IMAGE_LAYOUT_FILESYSTEM_COUNT}_MOUNTPOINT=${part_mountpoint}"
|
||||
|
||||
echo "FILESYSTEM_${IMAGE_LAYOUT_FILESYSTEM_COUNT}_CONTAINER_SIZE=${part_size_in_byte}"
|
||||
|
||||
echo "PARTITION_${part_idx}_FILESYSTEM_IDX=${IMAGE_LAYOUT_FILESYSTEM_COUNT}"
|
||||
IMAGE_LAYOUT_FILESYSTEM_COUNT="$(( IMAGE_LAYOUT_FILESYSTEM_COUNT + 1 ))"
|
||||
}
|
||||
|
||||
parse_image_layout_impl_partitioned_disk_table_GUID() {
|
||||
logi "Parsing GUID table"
|
||||
# reserve space for table header
|
||||
curr_part_offset=${GUID_TABLE_RESV_SIZE}
|
||||
curr_part_offset="(( ((curr_part_offset - 1) / GUID_TABLE_ALIGNMENT + 1) * GUID_TABLE_ALIGNMENT ))"
|
||||
has_flex_size_part=false
|
||||
for part_idx in $(seq 1 99); do
|
||||
if eval "[ -z \"\${PARTITION_${part_idx}_USAGE+x}\" ]"; then
|
||||
break
|
||||
fi
|
||||
logi "Parsing part ${part_idx}"
|
||||
|
||||
if $has_flex_size_part; then
|
||||
loge "No more partition is allowed after flex-size partition"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# PARTITION_xx_OFFSET
|
||||
# Ensure current part offset alignment
|
||||
part_offset_in_byte="$(eval echo \$\{PARTITION_"${part_idx}"_OFFSET:-0B\})"
|
||||
part_offset_in_byte="$(numfmt --from iec "${part_offset_in_byte%B}")"
|
||||
if [ "${part_offset_in_byte}" -ne 0 ]; then
|
||||
# Ensure alignment first
|
||||
aligned_part_offset="$(( ((part_offset_in_byte - 1) / GUID_TABLE_ALIGNMENT + 1) * GUID_TABLE_ALIGNMENT ))"
|
||||
if [ "${aligned_part_offset}" -ne "${part_offset_in_byte}" ]; then
|
||||
logw "Force aligning ${part_offset_in_byte} to ${aligned_part_offset}"
|
||||
fi
|
||||
# Then make sure it does not overlap
|
||||
if [ "${aligned_part_offset}" -lt "${curr_part_offset}" ]; then
|
||||
loge "Offset ${aligned_part_offset} overlaps with existing occupation ${curr_part_offset}"
|
||||
exit 1
|
||||
fi
|
||||
# Finally update curr_part_offset
|
||||
curr_part_offset="${aligned_part_offset}"
|
||||
fi
|
||||
# if the optional offset is not provided then use calculated one instead
|
||||
echo "PARTITION_${part_idx}_OFFSET=${curr_part_offset}"
|
||||
|
||||
# PARTITION_xx_SIZE
|
||||
# There's no special limitation about the partition size. But we only accept IEC scaling factor
|
||||
part_size_in_byte="$(eval echo \$\{PARTITION_"${part_idx}"_SIZE:-0B\})"
|
||||
part_size_in_byte="$(numfmt --from iec "${part_size_in_byte%B}")"
|
||||
if [ "${part_size_in_byte}" -eq 0 ]; then
|
||||
# no follow-up partition is allowed
|
||||
has_flex_size_part=true
|
||||
fi
|
||||
echo "PARTITION_${part_idx}_SIZE=${part_size_in_byte}"
|
||||
|
||||
# Then increase the part offset to next available position
|
||||
curr_part_offset="$(( ((curr_part_offset + part_size_in_byte - 1) / GUID_TABLE_ALIGNMENT + 1) * GUID_TABLE_ALIGNMENT ))"
|
||||
|
||||
# PARTITION_xx_NAME
|
||||
echo "PARTITION_${part_idx}_NAME=$(eval echo \$\{PARTITION_"${part_idx}"_NAME:-\})"
|
||||
|
||||
# PARTITION_xx_UUID
|
||||
part_uuid="$(eval echo \$\{PARTITION_"${part_idx}"_UUID:-\})"
|
||||
if [ -n "${part_uuid}" ]; then
|
||||
if ! echo "${part_uuid}" | sed -n '/^[0-9a-fA-F]\{8\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{12\}$/!q1'; then
|
||||
loge "Inavlid part UUID: ${part_uuid}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ -z "${part_uuid}" ]; then
|
||||
part_uuid="$(uuidgen)"
|
||||
fi
|
||||
echo "PARTITION_${part_idx}_UUID=${part_uuid}"
|
||||
|
||||
# PARTITION_xx_TYPE
|
||||
echo "PARTITION_${part_idx}_TYPE=$(eval echo \$\{PARTITION_"${part_idx}"_TYPE:-\})"
|
||||
# PARTITION_xx_ATTRS
|
||||
echo "PARTITION_${part_idx}_ATTRS=$(eval echo \$\{PARTITION_"${part_idx}"_ATTRS:-\})"
|
||||
|
||||
# PARTITION_xx_USAGE
|
||||
part_usage="$(eval echo \$\{PARTITION_"${part_idx}"_USAGE:-\})"
|
||||
if ! is_function "parse_image_layout_impl_partitioned_disk_table_GUID_part_usage_${part_usage}"; then
|
||||
loge "PARTITION_USAGE \"${part_usage}\" not implemented"
|
||||
exit 1
|
||||
fi
|
||||
echo "PARTITION_${part_idx}_USAGE=${part_usage}"
|
||||
"parse_image_layout_impl_partitioned_disk_table_GUID_part_usage_${part_usage}"
|
||||
done
|
||||
}
|
||||
|
||||
produce_image_GUID() {
|
||||
# Calculate the final image size
|
||||
total_partition_count=0
|
||||
for part_idx in $(seq 1 99); do
|
||||
if eval "[ -z \"\${PARTITION_${part_idx}_USAGE+x}\" ]"; then
|
||||
break
|
||||
fi
|
||||
total_partition_count="$(( total_partition_count + 1 ))"
|
||||
done
|
||||
last_part_offset="PARTITION_${total_partition_count}_OFFSET"
|
||||
last_part_offset="${!last_part_offset}"
|
||||
last_part_size="PARTITION_${total_partition_count}_SIZE"
|
||||
last_part_size="${!last_part_size}"
|
||||
if [ "${last_part_size}" -eq 0 ]; then
|
||||
last_part_fs_idx="PARTITION_${total_partition_count}_FILESYSTEM_IDX"
|
||||
last_part_fs_idx="${!last_part_fs_idx}"
|
||||
last_part_fs_mountpoint="FILESYSTEM_${last_part_fs_idx}_MOUNTPOINT"
|
||||
last_part_fs_mountpoint="${!last_part_fs_mountpoint}"
|
||||
last_part_fs_format="FILESYSTEM_${last_part_fs_idx}_FORMAT"
|
||||
last_part_fs_format="${!last_part_fs_format}"
|
||||
fs_img_file="$(echo "${last_part_fs_mountpoint}" | tr '/' ':').${last_part_fs_format}"
|
||||
last_part_size="$(du --apparent-size -b -s "${FS_IMG_DIR}/${fs_img_file}" | cut -f 1)"
|
||||
fi
|
||||
curr_offset="$(( last_part_offset + last_part_size ))"
|
||||
# Ensure the last partition owns the last usable sector
|
||||
curr_offset="$(( ((curr_offset - 1) / GUID_TABLE_SECTOR_SIZE + 1) * GUID_TABLE_SECTOR_SIZE ))"
|
||||
final_disk_size="$(( curr_offset + GUID_TABLE_RESV_SIZE ))"
|
||||
final_disk_size="$(( ((final_disk_size - 1) / GUID_TABLE_SECTOR_SIZE + 1) * GUID_TABLE_SECTOR_SIZE ))"
|
||||
|
||||
# Prepare the partition table
|
||||
OUTPUT_IMAGE="${OUTPUT_PREFIX}.img"
|
||||
rm -f "${OUTPUT_IMAGE}"
|
||||
logi "Allocating ${final_disk_size}B for ${OUTPUT_IMAGE}"
|
||||
truncate -s "${final_disk_size}" "${OUTPUT_IMAGE}"
|
||||
sgdisk -Z "${OUTPUT_IMAGE}" >/dev/null 2>&1
|
||||
# sgdisk operates on files that may have different sector size with out target image
|
||||
SECTOR_SIZE="$(sgdisk -p "${OUTPUT_IMAGE}" | sed -rn 's/Sector size \(logical\): ([0-9]+) bytes/\1/p')"
|
||||
# Make sure our offset alignment satisfies sector size
|
||||
if [ "$(( (GUID_TABLE_ALIGNMENT / SECTOR_SIZE) * SECTOR_SIZE ))" -ne "${GUID_TABLE_ALIGNMENT}" ]; then
|
||||
loge "Unsupported alignment between GUID_TABLE_ALIGNMENT (${GUID_TABLE_ALIGNMENT}) and SECTOR_SIZE (${SECTOR_SIZE})"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for part_idx in $(seq 1 ${total_partition_count}); do
|
||||
logi "Creating partition ${part_idx}"
|
||||
curr_part_size="PARTITION_${part_idx}_SIZE"
|
||||
curr_part_size="${!curr_part_size}"
|
||||
if [ "${curr_part_size}" -eq 0 ]; then
|
||||
# Must be the last partition
|
||||
curr_part_size="${last_part_size}"
|
||||
fi
|
||||
curr_part_offset="PARTITION_${part_idx}_OFFSET"
|
||||
curr_part_offset="${!curr_part_offset}"
|
||||
sgdisk --new "${part_idx}:$(( curr_part_offset / SECTOR_SIZE )):+$(( curr_part_size / SECTOR_SIZE ))" "${OUTPUT_IMAGE}" >/dev/null 2>&1
|
||||
curr_part_uuid="PARTITION_${part_idx}_UUID"
|
||||
curr_part_uuid="${!curr_part_uuid}"
|
||||
./partition_table_helper/gptcfg.sh "${OUTPUT_IMAGE}" set-uuid "${part_idx}" "${curr_part_uuid}"
|
||||
curr_part_name="PARTITION_${part_idx}_NAME"
|
||||
curr_part_name="${!curr_part_name}"
|
||||
./partition_table_helper/gptcfg.sh "${OUTPUT_IMAGE}" set-name "${part_idx}" "${curr_part_name}"
|
||||
curr_part_type="PARTITION_${part_idx}_TYPE"
|
||||
curr_part_type="${!curr_part_type}"
|
||||
curr_part_attrs="PARTITION_${part_idx}_ATTRS"
|
||||
curr_part_attrs="${!curr_part_attrs}"
|
||||
./partition_table_helper/gptcfg.sh "${OUTPUT_IMAGE}" set-type "${part_idx}" "${curr_part_type}" ${curr_part_attrs}
|
||||
|
||||
# Filling contents
|
||||
curr_part_content="PARTITION_${part_idx}_CONTENT"
|
||||
curr_part_content="${!curr_part_content}"
|
||||
dd conv=notrunc,sparse status=none \
|
||||
if="${curr_part_content}" \
|
||||
of="${OUTPUT_IMAGE}" \
|
||||
bs="${GUID_TABLE_SECTOR_SIZE}" \
|
||||
seek="$(( curr_part_offset / GUID_TABLE_SECTOR_SIZE ))"
|
||||
done
|
||||
logi "${OUTPUT_IMAGE} written."
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env false
|
||||
|
||||
is_function() {
|
||||
type "$1" 2>/dev/null | head -n 1 | grep 'function' > /dev/null
|
||||
}
|
||||
|
||||
setup_repo_yum() {
|
||||
mkdir -p "${ROOTFS_DIR}/etc/yum.repos.d"
|
||||
cp "${RECEIPE_DIR}"/repos.d/* "${ROOTFS_DIR}/etc/yum.repos.d"
|
||||
}
|
||||
|
||||
setup_repo() {
|
||||
logi "Preconfiguring package repo..."
|
||||
setup_repo_func="setup_repo_${PACKAGE_MANAGER}"
|
||||
if ! is_function "${setup_repo_func}" ; then
|
||||
loge "Package manager ${PACKAGE_MANAGER} not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"setup_repo_${PACKAGE_MANAGER}"
|
||||
}
|
||||
|
||||
execute_script_dir() {
|
||||
script_dir="$1"
|
||||
|
||||
find "${script_dir}" -maxdepth 1 -mindepth 1 -type d,l | sort | \
|
||||
while IFS= read -r line; do
|
||||
logi "Executing scripts: ${line}"
|
||||
bash -c "
|
||||
cd ${line} &&
|
||||
${2}
|
||||
${line}/entry.sh"
|
||||
done
|
||||
}
|
||||
|
||||
install_package_cleanup_yum() {
|
||||
yum --forcearch riscv64 --installroot="${ROOTFS_DIR}" clean all
|
||||
}
|
||||
|
||||
install_package_cleanup() {
|
||||
logi "Cleanup package installation"
|
||||
install_package_cleanup_func="install_package_cleanup_${PACKAGE_MANAGER}"
|
||||
if ! is_function "${install_package_cleanup_func}" ; then
|
||||
loge "Package manager ${PACKAGE_MANAGER} not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"install_package_cleanup_${PACKAGE_MANAGER}"
|
||||
}
|
||||
|
||||
install_package_list_yum() {
|
||||
# shellcheck shell=dash disable=SC2086
|
||||
yum --forcearch riscv64 --installroot="${ROOTFS_DIR}" -y install $1
|
||||
}
|
||||
|
||||
install_package_list() {
|
||||
logi "Installing package list: $1"
|
||||
install_package_list_func="install_package_list_${PACKAGE_MANAGER}"
|
||||
if ! is_function "${install_package_list_func}" ; then
|
||||
loge "Package manager ${PACKAGE_MANAGER} not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"install_package_list_${PACKAGE_MANAGER}" "$(tr '\n' ' ' < "$1")"
|
||||
}
|
||||
|
||||
install_package_group_yum() {
|
||||
# shellcheck shell=dash disable=SC2086
|
||||
yum --forcearch riscv64 --installroot="${ROOTFS_DIR}" -y groupinstall $1
|
||||
}
|
||||
|
||||
install_package_group() {
|
||||
logi "Installing package group: $1"
|
||||
install_package_group_func="install_package_group_${PACKAGE_MANAGER}"
|
||||
if ! is_function "${install_package_group_func}" ; then
|
||||
loge "Package manager ${PACKAGE_MANAGER} not supported yet."
|
||||
exit 1
|
||||
fi
|
||||
"install_package_group_${PACKAGE_MANAGER}" "$(tr '\n' ' ' < "$1")"
|
||||
}
|
||||
|
||||
install_packages() {
|
||||
logi "Install packages..."
|
||||
find "${RECEIPE_DIR}"/packages.d/ -maxdepth 1 -mindepth 1 -type f,d,l | sort | \
|
||||
while IFS= read -r line; do
|
||||
actualpath="$(readlink -f "${line}")"
|
||||
if [ -d "${actualpath}" ]; then
|
||||
if [ -f "${line}/packages.list" ]; then
|
||||
install_package_list "${line}/packages.list"
|
||||
elif [ -f "${line}/packages.group" ]; then
|
||||
install_package_group "${line}/packages.group"
|
||||
else
|
||||
logw "No package list, ignoring ${line}"
|
||||
continue
|
||||
fi
|
||||
if [ -d "${line}/post.d" ]; then
|
||||
execute_script_dir "${line}/post.d" "${1}"
|
||||
fi
|
||||
elif [ -f "${actualpath}" ]; then
|
||||
if echo "${line}" | grep ".*.list" > /dev/null; then
|
||||
install_package_list "${line}"
|
||||
elif echo "${line}" | grep ".*.group" > /dev/null; then
|
||||
install_package_group "${line}"
|
||||
else
|
||||
logw "Unsupported package list, ignoring ${line}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
install_package_cleanup
|
||||
}
|
||||
|
||||
post_scripts() {
|
||||
if [ -d "$(readlink -f "${RECEIPE_DIR}/post.d")" ]; then
|
||||
logi "Post configuring..."
|
||||
execute_script_dir "${RECEIPE_DIR}/post.d" "${1}"
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user