Skip to content

Commit f730a86

Browse files
authored
rpardini's May'24 fix batch: slim for 2Gb RAM devices (#225)
> - recent userspace additions took the initramfs size near or over the 900mb mark for certain kernels. > - initramfs (gzipped cpio) is uncompressed by bootloader and mounted on tmpfs by kernel. > - tmpfs allows only 50% of physical RAM by default, and default can't be changed easily. > - slim down both the userspace (by stripping / removing some / etc) and the Armbian kernels (by removing modules) > - with those we're back below 900mb uncompressed again, and the default x86 hook tarball is down from 223 to 180mb compressed. > - add a check for uncompressed cpio size at 900mb; warn in GHA if it is ever hit again. > - also includes: fixes for ttyAML consoles, better logging, some dev/debug options used for batch > > note: review is easier if done commit-by-commit; sent a large batch due to same-line changes across them ---- #### build: common: better logging & emit notice/warn/error also to GHA workflow commands - see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-notice-message - introduces `notice` level, which is just like `info` but brighter and goes to GHA - also: curb warning about USE_KERNEL_ID down to info #### kernel: armbian: fix: use ORAS binary appropriate to the (host) arch; bump ORAS to 1.2.0-rc.1 (from beta.1) - otherwise can't build those "kernels" on arm64-only & qemu+binfmt-deprived hosts #### build: introduce `OUTPUT_TARBALL_FILELIST=yes` to include LK's `--format tar` output and its filelist - useful during development for: - debugging esoteric issue with file permissions - checking the space usage distribution, so we can slim down where needed #### kernel: armbian: ensure kernel.tar contains entry for the / (root) directory - quite esoteric, but it seems LinuxKit uses the kernel.tar's root entry as its own entry - if that is missing, then the final product rootfs will have root dir with very strange permissions #### kernel: armbian: don't flood output with tar's verbose option #### kernel: armbian: remove some heavy kernel modules (so it fits in 2Gb RAM) - Armbian kernels are meant for general-purpose initrd's, and including all modules is overkill - this allows to boot on 2Gb RAM machines (tmpfs allows only up to 50% RAM) #### images: slim down golang binaries, by building without DWARF/debug symbols, stripping prebuilts, and removing unneeded bins - strip golang binaries (both during build with ldflags and prebuilt ones with 'strip'/binutils) - don't ship apk caches - we won't use docker-buildx nor docker-compose bins, which are huge; remove them - remove stray 'hook-bootkit' binary from source directory (leftover from ?) #### hook: add handling for ttyAML0/1 (used on Amlogic SoCs) - complements a68b629 - create /dev devices with 243 major and 0/1 minor - add to securetty #### build: introduce check for initramfs size > 900Mb and warn/notice - those will most likely fail to boot on 2Gb RAM machines - initramfs will by default use tmpfs (which defaults to 50% ram), not ramfs
2 parents 393c1af + c5024da commit f730a86

File tree

11 files changed

+80
-17
lines changed

11 files changed

+80
-17
lines changed

bash/common.sh

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
#!/usr/bin/env bash
22

33
# logger utility, output ANSI-colored messages to stderr; first argument is level (debug/info/warn/error), all other arguments are the message.
4-
declare -A log_colors=(["debug"]="0;36" ["info"]="0;32" ["warn"]="0;33" ["error"]="0;31")
5-
declare -A log_emoji=(["debug"]="🐛" ["info"]="📗" ["warn"]="🚧" ["error"]="🚨")
4+
declare -A log_colors=(["debug"]="0;36" ["info"]="0;32" ["notice"]="1;32" ["warn"]="1;33" ["error"]="1;31")
5+
declare -A log_emoji=(["debug"]="🐛" ["info"]="🌿" ["notice"]="🌱" ["warn"]="🚸" ["error"]="🚨")
6+
declare -A log_gha_levels=(["notice"]="notice" ["warn"]="warning" ["error"]="error")
67
function log() {
78
declare level="${1}"
89
shift
910
[[ "${level}" == "debug" && "${DEBUG}" != "yes" ]] && return # Skip debugs unless DEBUG=yes is set in the environment
10-
declare color="${log_colors[${level}]}"
11+
# If running on GitHub Actions, and level exists in log_gha_levels...
12+
if [[ -n "${GITHUB_ACTIONS}" && -n "${log_gha_levels[${level}]}" ]]; then
13+
echo "::${log_gha_levels[${level}]} ::${*}" >&2
14+
fi
15+
# Normal output
16+
declare color="\033[${log_colors[${level}]}m"
1117
declare emoji="${log_emoji[${level}]}"
18+
declare ansi_reset="\033[0m"
1219
level=$(printf "%-5s" "${level}") # pad to 5 characters before printing
13-
echo -e "${emoji} \033[${color}m${SECONDS}: [${level}] $*\033[0m" >&2
20+
echo -e "${emoji} ${ansi_reset}[${color}${level}${ansi_reset}] ${color}${*}${ansi_reset}" >&2
1421
}
1522

1623
function install_dependencies() {

bash/json-matrix.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function prepare_json_matrix() {
7373

7474
if [[ "${matrix_type}" == "KERNEL" ]]; then # special case for kernel builds, if USE_KERNEL_ID is set, skip this kernel
7575
if [[ -n "${kernel_info[USE_KERNEL_ID]}" ]]; then
76-
log warn "Skipping build of kernel '${kernel}' due to it having USE_KERNEL_ID set to '${kernel_info[USE_KERNEL_ID]}'"
76+
log info "Skipping build of kernel '${kernel}' due to it having USE_KERNEL_ID set to '${kernel_info[USE_KERNEL_ID]}'"
7777
continue
7878
fi
7979
fi

bash/kernel/kernel_armbian.sh

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,15 @@ function calculate_kernel_version_armbian() {
4545

4646
declare -g ARMBIAN_KERNEL_DOCKERFILE="kernel/Dockerfile.autogen.armbian.${inventory_id}"
4747

48-
declare oras_version="1.2.0-beta.1" # @TODO bump this once it's released; yes it's much better than 1.1.x's
49-
declare oras_down_url="https://github.com/oras-project/oras/releases/download/v${oras_version}/oras_${oras_version}_linux_amd64.tar.gz"
48+
declare oras_version="1.2.0-rc.1" # @TODO bump this once it's released; yes it's much better than 1.1.x's
49+
# determine the arch to download from current arch
50+
declare oras_arch="unknown"
51+
case "$(uname -m)" in
52+
"x86_64") oras_arch="amd64" ;;
53+
"aarch64") oras_arch="arm64" ;;
54+
*) log error "ERROR: ARCH $(uname -m) not supported by ORAS? check https://github.com/oras-project/oras/releases" && exit 1 ;;
55+
esac
56+
declare oras_down_url="https://github.com/oras-project/oras/releases/download/v${oras_version}/oras_${oras_version}_linux_${oras_arch}.tar.gz"
5057

5158
# Lets create a Dockerfile that will be used to obtain the artifacts needed, using ORAS binary
5259
echo "Creating Dockerfile '${ARMBIAN_KERNEL_DOCKERFILE}'... "
@@ -83,8 +90,16 @@ function calculate_kernel_version_armbian() {
8390
# Get the kernel image...
8491
RUN cp -v boot/vmlinuz* /armbian/output/kernel
8592
86-
# Create a tarball with the modules in lib
87-
RUN tar -cvf /armbian/output/kernel.tar lib
93+
# Create a tarball with the modules in lib.
94+
# Important: this tarball needs to have permissions for the root directory included! Otherwise linuxkit rootfs will have the wrong permissions on / (root)
95+
WORKDIR /armbian/modules_only
96+
RUN mv /armbian/image/lib /armbian/modules_only/
97+
RUN echo "Before cleaning: " && du -h -d 10 -x . | sort -h | tail -n 20
98+
# Trim the kernel modules to save space; hopefully your required hardware is not included here
99+
RUN rm -rfv ./lib/modules/*/kernel/drivers/net/wireless ./lib/modules/*/kernel/sound ./lib/modules/*/kernel/drivers/media
100+
RUN rm -rfv ./lib/modules/*/kernel/drivers/infiniband
101+
RUN echo "After cleaning: " && du -h -d 10 -x . | sort -h | tail -n 20
102+
RUN tar -cf /armbian/output/kernel.tar .
88103
89104
# Create a tarball with the dtbs in usr/lib/linux-image-*
90105
RUN { cd usr/lib/linux-image-* || { echo "No DTBS for this arch, empty tar..." && mkdir -p usr/lib/linux-image-no-dtbs && cd usr/lib/linux-image-* ; } ; } && pwd && du -h -d 1 . && tar -czvf /armbian/output/dtbs.tar.gz . && ls -lah /armbian/output/dtbs.tar.gz

bash/linuxkit.sh

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,31 @@ function linuxkit_build() {
8484
declare -a lk_args=(
8585
"--docker"
8686
"--arch" "${kernel_info['DOCKER_ARCH']}"
87-
"--format" "kernel+initrd"
8887
"--name" "hook"
8988
"--cache" "${lk_cache_dir}"
9089
"--dir" "${lk_output_dir}"
9190
"hook.${inventory_id}.yaml" # the linuxkit configuration file
9291
)
9392

93+
if [[ "${OUTPUT_TARBALL_FILELIST:-"no"}" == "yes" ]]; then
94+
log info "OUTPUT_TARBALL_FILELIST=yes; Building Hook (tar/filelist) with kernel ${inventory_id} using linuxkit: ${lk_args[*]}"
95+
"${linuxkit_bin}" build "--format" "tar" "${lk_args[@]}"
96+
fi
97+
9498
log info "Building Hook with kernel ${inventory_id} using linuxkit: ${lk_args[*]}"
95-
"${linuxkit_bin}" build "${lk_args[@]}"
99+
"${linuxkit_bin}" build "--format" "kernel+initrd" "${lk_args[@]}"
100+
101+
declare initramfs_path="${lk_output_dir}/hook-initrd.img"
102+
# initramfs_path is a gzipped file. obtain the uncompressed byte size, without decompressing it
103+
declare -i initramfs_size_bytes=0
104+
initramfs_size_bytes=$(gzip -l "${initramfs_path}" | tail -n 1 | awk '{print $2}')
105+
log info "Uncompressed initramfs size in bytes: ${initramfs_size_bytes}"
106+
# If the size is larger than 900mb, it is unlikely to boot on a 2gb RAM machine. Warn.
107+
if [[ "${initramfs_size_bytes}" -gt 943718400 ]]; then
108+
log warn "${inventory_id}: Uncompressed initramfs size (${initramfs_size_bytes} bytes) is larger than 900mb; it may not boot on a 2gb RAM machine."
109+
else
110+
log notice "${inventory_id}: Uncompressed initramfs size (${initramfs_size_bytes} bytes) is smaller than 900mb."
111+
fi
96112

97113
if [[ "${LK_RUN}" == "qemu" ]]; then
98114
linuxkit_run_qemu
@@ -137,6 +153,13 @@ function linuxkit_build() {
137153
rm -rf "${dtbs_tmp_dir}"
138154
rm "${lk_output_dir}/dtbs-${OUTPUT_ID}.tar.gz"
139155

156+
if [[ "${OUTPUT_TARBALL_FILELIST:-"no"}" == "yes" ]]; then
157+
log info "OUTPUT_TARBALL_FILELIST=yes; including tar and filelist in output."
158+
mv -v "${lk_output_dir}/hook.tar" "out/hook/hook_rootfs_${OUTPUT_ID}.tar"
159+
tar --list -vf "out/hook/hook_rootfs_${OUTPUT_ID}.tar" > "out/hook/hook_rootfs_${OUTPUT_ID}.filelist"
160+
fi
161+
162+
# finally clean up the hook-specific out dir
140163
rm -rf "${lk_output_dir}"
141164

142165
# tar the files into out/hook.tar in such a way that vmlinuz and initramfs are at the root of the tar; pigz it

images/hook-bootkit/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM golang:1.21-alpine as dev
22
COPY . /src/
33
WORKDIR /src
44
RUN go mod download
5-
RUN CGO_ENABLED=0 go build -a -ldflags '-w -extldflags "-static"' -o /bootkit
5+
RUN CGO_ENABLED=0 go build -a -ldflags '-s -w -extldflags "-static"' -o /bootkit
66

77
FROM alpine
88
COPY --from=dev /bootkit .

images/hook-bootkit/hook-bootkit

-9.07 MB
Binary file not shown.

images/hook-containerd/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ RUN mkdir -p $GOPATH/src/github.com/containerd && \
1818
git checkout $CONTAINERD_COMMIT
1919
RUN apk add --no-cache btrfs-progs-dev gcc libc-dev linux-headers make libseccomp-dev
2020
WORKDIR $GOPATH/src/github.com/containerd/containerd
21-
RUN make binaries EXTRA_FLAGS="-buildmode pie" EXTRA_LDFLAGS='-extldflags "-fno-PIC -static"' BUILDTAGS="static_build no_devmapper"
21+
RUN make binaries EXTRA_FLAGS="-buildmode pie" EXTRA_LDFLAGS='-w -s -extldflags "-fno-PIC -static"' BUILDTAGS="static_build no_devmapper"
2222

2323
# install nerdctl
2424
RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then ARCHITECTURE=amd64; elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then ARCHITECTURE=arm64; else ARCHITECTURE=amd64; fi \

images/hook-docker/Dockerfile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
FROM golang:1.20-alpine as dev
22
COPY . /src/
33
WORKDIR /src
4-
RUN CGO_ENABLED=0 go build -a -ldflags '-w -extldflags "-static"' -o /hook-docker
4+
RUN CGO_ENABLED=0 go build -a -ldflags '-s -w -extldflags "-static"' -o /hook-docker
55

66
FROM docker:26.1.0-dind
77
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories
8-
RUN apk update; apk add kexec-tools
8+
RUN apk update && apk add kexec-tools binutils && rm -rf /var/cache/apk/*
9+
# Won't use docker-buildx nor docker-compose
10+
RUN rm -rf /usr/local/libexec/docker/cli-plugins
11+
# Strip some large binaries
12+
RUN strip /usr/local/bin/docker /usr/local/bin/dockerd /usr/local/bin/docker-proxy /usr/local/bin/runc
13+
# Purge binutils package after stripping
14+
RUN apk del binutils
915
COPY --from=dev /hook-docker .
1016
ENTRYPOINT ["/hook-docker"]

images/hook-mdev/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM alpine
22

33
USER root:root
44

5-
RUN apk add --no-cache mdev-conf
5+
RUN apk add --no-cache mdev-conf && rm -rf /var/cache/apk/*
66

77
CMD ["mdev", "-v", "-df"]
88

images/hook-runc/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ RUN mkdir -p $GOPATH/src/github.com/opencontainers && \
1919
git clone https://github.com/opencontainers/runc.git
2020
WORKDIR $GOPATH/src/github.com/opencontainers/runc
2121
RUN git checkout $RUNC_COMMIT
22-
RUN make static BUILDTAGS="seccomp" EXTRA_FLAGS="-buildmode pie" EXTRA_LDFLAGS="-extldflags \\\"-fno-PIC -static\\\""
22+
RUN make static BUILDTAGS="seccomp" EXTRA_FLAGS="-buildmode pie" EXTRA_LDFLAGS="-s -w -extldflags \\\"-fno-PIC -static\\\""
2323
RUN cp runc /usr/bin/
2424

2525
RUN mkdir -p /etc/init.d && ln -s /usr/bin/service /etc/init.d/010-onboot

0 commit comments

Comments
 (0)