Skip to content

Commit 6fc9c76

Browse files
authored
Merge pull request #1098 from huww98/rewrite-dockerfile
build: rewrite dockerfile to distroless
2 parents 71912a2 + 3092431 commit 6fc9c76

File tree

7 files changed

+348
-108
lines changed

7 files changed

+348
-108
lines changed

build/build-all-multi.sh

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#!/usr/bin/env bash
22
set -ex
33

4-
BUILD_ARGS=( \
5-
--frontend dockerfile.v0 \
6-
--local context=. \
7-
--local dockerfile=build/multi \
8-
--opt filename=Dockerfile.multi \
9-
--opt platform=linux/amd64,linux/arm64 \
10-
--opt build-arg:CSI_VERSION=$(git describe --tags --always --dirty)
4+
BUILD_ARGS=(
5+
--frontend dockerfile.v0
6+
--local context=.
7+
--local dockerfile=build/multi
8+
--opt filename=Dockerfile.multi
9+
--opt "platform=linux/amd64,linux/arm64"
10+
--opt "build-arg:CSI_VERSION=$(git describe --tags --always --dirty)"
11+
--opt "build-arg:SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)"
1112
)
1213
BUILD_ARGS+=("$@")
1314

build/gather-node-deps.sh

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# This directory is distroless specific, and recognized by syft
5+
mkdir -p /staging-node/var/lib/dpkg/status.d
6+
7+
DEPS=(
8+
/etc/mke2fs.conf /sbin/{fsck,mkfs,mount,umount}.{ext{2,3,4},xfs,nfs}
9+
/usr/bin/{mount,umount,lspci,lsof,chmod,grep,tail,nsenter}
10+
/usr/sbin/{fsck,mkfs,sfdisk,losetup,blockdev}
11+
/sbin/dumpe2fs /sbin/resize2fs
12+
/usr/sbin/xfs_io /usr/sbin/xfs_growfs
13+
)
14+
15+
declare -A FILE_PACKAGES
16+
for line in $(dpkg-query --show --showformat 'PKG_NAME:${Package}\n${db-fsys:Files}'); do
17+
if [[ "$line" = PKG_NAME:* ]]; then
18+
pkg=${line#PKG_NAME:}
19+
else
20+
FILE_PACKAGES[$line]=$pkg
21+
fi
22+
done
23+
echo "indexed ${#FILE_PACKAGES[@]} files"
24+
25+
MTIME=0
26+
gather_dep() {
27+
local source target t pkg copyright
28+
# resolve all but last component of symlink
29+
source=$(realpath "$(dirname "$1")")/$(basename "$1")
30+
31+
# find the package that contains the source
32+
pkg=${FILE_PACKAGES[$source]}
33+
if [ -z "$pkg" ] && [[ "$source" = /usr/* ]]; then
34+
# retry without /usr prefix
35+
# use source path matching dpkg for SBOM to work, because /lib is not linked to /usr/lib in distroless
36+
source="${source#/usr}"
37+
pkg=${FILE_PACKAGES[$source]}
38+
fi
39+
if [ -z "$pkg" ]; then
40+
echo "failed to find package for $source"
41+
return 1
42+
fi
43+
if [ -e "/base$source" ]; then
44+
echo "$source already exist in base"
45+
return 0
46+
fi
47+
48+
[ -e "/staging-node$source" ] && return 0
49+
if [ -h "$source" ]; then
50+
target=$(realpath "$source")
51+
echo "gathering link $source => $target"
52+
gather_dep "$target"
53+
fi
54+
echo "gathering dep $pkg: $source"
55+
t=$(stat -c '%Y' "$source")
56+
[ "$t" -gt "$MTIME" ] && MTIME=$t
57+
cp -dp --parents "$source" /staging-node
58+
59+
# deb package metadata is useful for SBOM
60+
[ -e "/staging-node/var/lib/dpkg/status.d/$pkg" ] && return 0
61+
echo "installing deb package $pkg metadata"
62+
dpkg-query --status "$pkg" > "/staging-node/var/lib/dpkg/status.d/$pkg"
63+
dpkg-query --control-show "$pkg" md5sums > "/staging-node/var/lib/dpkg/status.d/$pkg.md5sums"
64+
copyright="/usr/share/doc/$pkg/copyright"
65+
if [ -e "$copyright" ]; then
66+
echo "installing deb package $pkg copyright"
67+
cp -dp --parents "$copyright" /staging-node
68+
fi
69+
}
70+
for f in "${DEPS[@]}"; do
71+
if ! [ -e "$f" ]; then
72+
echo "$f does not exist"
73+
continue
74+
fi
75+
gather_dep "$f"
76+
done
77+
78+
mapfile -t LIBS < <(ldd /staging-node/{usr/,}{bin,sbin}/* 2>/dev/null | grep -Po '(?<= => )[^ ]+' | sort -u)
79+
for f in "${LIBS[@]}"; do
80+
gather_dep "$f"
81+
done
82+
echo "latest mtime is $(date --date "@$MTIME" --iso-8601=seconds)"
83+
find /staging-node -type d -exec touch --date="@$MTIME" {} +
84+
touch --date="@$MTIME" /staging-node/var/lib/dpkg/status.d/*

build/lib/init.sh

Lines changed: 63 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/sh
2+
# shellcheck shell=busybox
23

34
# skip all the setup if running in provisioner mode
45
if [ "$SERVICE_TYPE" = "provisioner" ]; then
@@ -16,30 +17,18 @@ run_nas="false"
1617
mkdir -p /var/log/alicloud/
1718
mkdir -p /host/etc/kubernetes/volumes/disk/uuid
1819

19-
HOST_CMD="/usr/bin/nsenter --mount=/proc/1/ns/mnt"
20+
host_cmd() { nsenter --mount=/proc/1/ns/mnt "$@"; }
2021
HOST_ROOT="/proc/1/root"
2122

22-
host_os="centos"
23-
2423
OS_RELEASE=/etc/os-release
2524
if ! [ -f $HOST_ROOT$OS_RELEASE ]; then
2625
OS_RELEASE=/usr/lib/os-release
2726
fi
28-
if [ -f $HOST_ROOT$OS_RELEASE ]; then
29-
OS_RELEASE_ID=$(grep -oP '(?<=^ID=).+' $HOST_ROOT$OS_RELEASE | tr -d '"')
30-
if [ -n "$OS_RELEASE_ID" ]; then
31-
host_os="$OS_RELEASE_ID"
32-
33-
if [[ $OS_RELEASE_ID = alinux ]]; then
34-
OS_RELEASE_VERSION_ID=$(grep -oP '(?<=^VERSION_ID=).+' $HOST_ROOT$OS_RELEASE | tr -d '"')
35-
host_os="alinux$(echo $OS_RELEASE_VERSION_ID | cut -d'.' -f1)"
36-
fi
37-
fi
38-
fi
39-
echo "detected host os: $host_os"
4027

28+
OS_RELEASE_ID=$(. $HOST_ROOT$OS_RELEASE; echo "$ID")
29+
OS_RELEASE_VERSION_ID=$(. $HOST_ROOT$OS_RELEASE; echo "$VERSION_ID")
4130
ARCH=$(uname -m)
42-
echo "detected host arch: $ARCH"
31+
echo "detected host OS: $OS_RELEASE_ID, version: $OS_RELEASE_VERSION_ID, arch: $ARCH"
4332

4433
cleanup_old_staging_path() (
4534
echo cleaning up old volume staging path. # kubelet will mount the new path at startup.
@@ -60,7 +49,7 @@ if [ -d "$OLD_STAGING_PATH" ]; then
6049
fi
6150

6251
## check which plugin is running
63-
for item in $@;
52+
for item in "$@";
6453
do
6554
if [ "$item" = "--driver=ossplugin.csi.alibabacloud.com" ]; then
6655
echo "Running oss plugin...."
@@ -77,11 +66,9 @@ do
7766
run_nas="true"
7867
mkdir -p "$KUBELET_ROOT_DIR/csi-plugins/nasplugin.csi.alibabacloud.com"
7968
rm -rf "$KUBELET_ROOT_DIR/plugins/nasplugin.csi.alibabacloud.com/csi.sock"
80-
elif [[ $item==*--driver=* ]]; then
81-
tmp=${item}
82-
driver_types=${tmp#*--driver=}
83-
driver_type_array=(${driver_types//,/ })
84-
for driver_type in ${driver_type_array[@]};
69+
elif [[ "$item" = *--driver=* ]]; then
70+
IFS=,
71+
for driver_type in ${item#*--driver=};
8572
do
8673
if [ "$driver_type" = "oss" ]; then
8774
echo "Running oss plugin...."
@@ -103,6 +90,7 @@ do
10390
run_pov="true"
10491
fi
10592
done
93+
unset IFS
10694
fi
10795
done
10896

@@ -112,12 +100,12 @@ if [ "$SKIP_UPDATEDB_CONFIG" != "true" ]; then
112100
if [ -f /host/etc/cron.daily/mlocate ]; then
113101
if [ -f /host/etc/updatedb.conf ]; then
114102
sed -i 's/PRUNE_BIND_MOUNTS.*$/PRUNE_BIND_MOUNTS = \"yes\"/g' /host/etc/updatedb.conf
115-
if ! grep "^PRUNEFS" /host/etc/updatedb.conf | grep -q --fixed-strings "fuse.ossfs"; then
103+
if ! grep "^PRUNEFS" /host/etc/updatedb.conf | grep -q -F "fuse.ossfs"; then
116104
PRUNEFS="fuse.ossfs"
117105
echo "add PRUNEFS: $PRUNEFS to /etc/updatedb.conf"
118106
sed -i "s|PRUNEFS\s*=\s*\"|&${PRUNEFS//|/\\|} |" /host/etc/updatedb.conf
119107
fi
120-
if ! grep "^PRUNEPATHS" /host/etc/updatedb.conf | grep -q --fixed-strings "$KUBELET_ROOT_DIR"; then
108+
if ! grep "^PRUNEPATHS" /host/etc/updatedb.conf | grep -q -F "$KUBELET_ROOT_DIR"; then
121109
PRUNEPATHS="$KUBELET_ROOT_DIR"
122110
if [ "$KUBELET_ROOT_DIR" = "/var/lib/kubelet" ]; then
123111
PRUNEPATHS="$PRUNEPATHS /var/lib/container/kubelet"
@@ -134,15 +122,15 @@ if [ "$DISABLE_CSIPLUGIN_CONNECTOR" != "true" ] && [ "$run_nas" = "true" ]; then
134122
## install/update csi connector
135123
updateConnector="true"
136124
systemdDir="/host/usr/lib/systemd/system"
137-
if [[ ${host_os} == "lifsea" ]]; then
125+
if [ "$OS_RELEASE_ID" = "lifsea" ]; then
138126
systemdDir="/host/etc/systemd/system"
139127
fi
140128
if [ ! -f "/host/etc/csi-tool/csiplugin-connector" ]; then
141129
mkdir -p /host/etc/csi-tool/
142130
echo "mkdir /etc/csi-tool/ directory..."
143131
else
144-
oldmd5=`md5sum /host/etc/csi-tool/csiplugin-connector | awk '{print $1}'`
145-
newmd5=`md5sum /csi/csiplugin-connector | awk '{print $1}'`
132+
oldmd5=$(md5sum /host/etc/csi-tool/csiplugin-connector | awk '{print $1}')
133+
newmd5=$(md5sum /csi/csiplugin-connector | awk '{print $1}')
146134
if [ "$oldmd5" = "$newmd5" ]; then
147135
updateConnector="false"
148136
else
@@ -163,14 +151,14 @@ if [ "$DISABLE_CSIPLUGIN_CONNECTOR" != "true" ] && [ "$run_nas" = "true" ]; then
163151

164152
# install/update csiplugin connector service
165153
updateConnectorService="true"
166-
if [[ ! -z "${PLUGINS_SOCKETS}" ]];then
154+
if [ -n "${PLUGINS_SOCKETS}" ];then
167155
sed -i 's/Restart=always/Restart=on-failure/g' /csi/csiplugin-connector.service
168156
sed -i '/^\[Service\]/a Environment=\"WATCHDOG_SOCKETS_PATH='"${PLUGINS_SOCKETS}"'\"' /csi/csiplugin-connector.service
169157
fi
170158
if [ -f "$systemdDir/csiplugin-connector.service" ];then
171159
echo "Check csiplugin-connector.service...."
172-
oldmd5=`md5sum $systemdDir/csiplugin-connector.service | awk '{print $1}'`
173-
newmd5=`md5sum /csi/csiplugin-connector.service | awk '{print $1}'`
160+
oldmd5=$(md5sum $systemdDir/csiplugin-connector.service | awk '{print $1}')
161+
newmd5=$(md5sum /csi/csiplugin-connector.service | awk '{print $1}')
174162
if [ "$oldmd5" = "$newmd5" ]; then
175163
updateConnectorService="false"
176164
else
@@ -182,10 +170,9 @@ if [ "$DISABLE_CSIPLUGIN_CONNECTOR" != "true" ] && [ "$run_nas" = "true" ]; then
182170
echo "Install csiplugin connector service...."
183171
cp /csi/csiplugin-connector.service $systemdDir/csiplugin-connector.service
184172
echo "Starting systemctl daemon-reload."
185-
for((i=1;i<=10;i++));
173+
for i in $(seq 10);
186174
do
187-
${HOST_CMD} systemctl daemon-reload
188-
if [ $? -eq 0 ]; then
175+
if host_cmd systemctl daemon-reload; then
189176
break
190177
else
191178
echo "Starting retry again systemctl daemon-reload.retry count:$i"
@@ -196,10 +183,9 @@ if [ "$DISABLE_CSIPLUGIN_CONNECTOR" != "true" ] && [ "$run_nas" = "true" ]; then
196183

197184
rm -rf /var/log/alicloud/connector.pid
198185
echo "Starting systemctl enable csiplugin-connector.service."
199-
for((i=1;i<=5;i++));
186+
for i in $(seq 5);
200187
do
201-
${HOST_CMD} systemctl enable csiplugin-connector.service
202-
if [ $? -eq 0 ]; then
188+
if host_cmd systemctl enable csiplugin-connector.service; then
203189
break
204190
else
205191
echo "Starting retry again systemctl enable csiplugin-connector.service.retry count:$i"
@@ -208,10 +194,9 @@ if [ "$DISABLE_CSIPLUGIN_CONNECTOR" != "true" ] && [ "$run_nas" = "true" ]; then
208194
done
209195

210196
echo "Starting systemctl restart csiplugin-connector.service."
211-
for((i=1;i<=5;i++));
197+
for i in $(seq 5);
212198
do
213-
${HOST_CMD} systemctl restart csiplugin-connector.service
214-
if [ $? -eq 0 ]; then
199+
if host_cmd systemctl restart csiplugin-connector.service; then
215200
break
216201
else
217202
echo "Starting retry again systemctl restart csiplugin-connector.service.retry count:$i"
@@ -222,41 +207,52 @@ fi
222207

223208
echo "Start checking if the host system packages needs to be installed"
224209

225-
if $HOST_CMD dnf --version; then
226-
echo "dnf is available"
227-
PKG_CMD=(dnf install -y)
228-
HAS_DNF=true
229-
HAS_YUM=true
230-
elif $HOST_CMD yum --version; then
231-
echo "yum is available"
210+
dnf_install() {
211+
host_cmd dnf install -y "$@"
212+
}
213+
214+
yum_install() {
232215
# yum install is not idempotent, so we need to check if the package is already installed.
233216
# yum also fails if the already installed version is newer, so we need to downgrade.
234217
# fail if both install and downgrade fail
235-
PKG_CMD=(sh -c 'if rpm --query $(rpm --query --package $1); then
236-
echo $1 already installed;
218+
# shellcheck disable=SC2016 # the expansion should happen on host, not in container.
219+
host_cmd sh -c 'if rpm --query $(rpm --query --package "$1"); then
220+
echo "$1 already installed";
237221
else
238-
yum install -y $1 || yum downgrade -y $1;
239-
fi' install_pkg)
240-
HAS_YUM=true
241-
elif $HOST_CMD apt-get --version; then
222+
yum install -y "$1" || yum downgrade -y "$1";
223+
fi' install_pkg "$1"
224+
}
225+
226+
apt_install() {
227+
host_cmd apt-get install -y --allow-downgrades "$@"
228+
}
229+
230+
if host_cmd dnf --version; then
231+
echo "dnf is available"
232+
PKG_MGR=dnf
233+
SUPPORT_RPM=true
234+
elif host_cmd yum --version; then
235+
echo "yum is available"
236+
PKG_MGR=yum
237+
SUPPORT_RPM=true
238+
elif host_cmd apt-get --version; then
242239
echo "apt-get is available"
243-
PKG_CMD=(apt-get install -y --allow-downgrades)
244-
HAS_APT=true
240+
PKG_MGR=apt
245241
fi
246242

247243
# idempotent package installation
248244
# downgrade if the already installed version is newer than the one we want to install
249-
function install_package() {
250-
cp /root/$1 /host/etc/csi-tool/
251-
if [ -z $PKG_CMD ]; then
245+
install_package() {
246+
cp "/root/$1" /host/etc/csi-tool/
247+
if [ -z "$PKG_MGR" ]; then
252248
echo "no package manager found"
253249
return 1
254250
fi
255-
${HOST_CMD} "${PKG_CMD[@]}" /etc/csi-tool/$1 || {
251+
"${PKG_MGR}_install" "/etc/csi-tool/$1" || {
256252
echo "failed to install $1"
257253
return 1
258254
}
259-
rm -f /host/etc/csi-tool/$1
255+
rm -f "/host/etc/csi-tool/$1"
260256
}
261257

262258
## CPFS-NAS plugin setup
@@ -280,35 +276,35 @@ if [ "$ARCH" = "x86_64" ] && [ "$run_nas" = "true" ]; then
280276
if [ $install_utils = "true" ]; then
281277
# cpfs-nas nas-rich-client common rpm
282278
echo "installing aliyun-alinas-utils"
283-
if [ "$HAS_YUM" = "true" ]; then
279+
if [ "$SUPPORT_RPM" = "true" ]; then
284280
PKG=aliyun-alinas-utils-1.1-8.20240527201444.2012cc.al7.noarch.rpm
285-
elif [ "$HAS_APT" = "true" ]; then
281+
elif [ "$PKG_MGR" = "apt" ]; then
286282
PKG=aliyun-alinas-utils-1.1-8.deb
287283
else
288284
echo "WARN: no supported package manager found, skip install aliyun-alinas-utils"
289285
install_utils="false"
290286
fi
291287
if [ $install_utils = "true" ]; then
292-
install_package $PKG || exit $?
288+
install_package "$PKG" || exit $?
293289
fi
294290
fi
295291

296-
if [ $host_os != "alinux2" ] && [ $install_efc = "true" ]; then
292+
if { [ "$OS_RELEASE_ID" != "alinux" ] || [[ "$OS_RELEASE_VERSION_ID" != 2.* ]]; } && [ $install_efc = "true" ]; then
297293
echo "WARN: skip install efc because host os is not alinux2"
298294
install_efc="false"
299295
fi
300296
if [ $install_efc = "true" ]; then
301297
# nas-rich-client rpm
302298
echo "installing alinas-efc"
303299
cp /root/alinas-efc-1.2-3.x86_64.rpm /host/etc/csi-tool/
304-
${HOST_CMD} yum install -y /etc/csi-tool/alinas-efc-1.2-3.x86_64.rpm
300+
host_cmd yum install -y /etc/csi-tool/alinas-efc-1.2-3.x86_64.rpm
305301

306302
echo "checking alinas-efc-1.2-3.x86_64 installed"
307-
${HOST_CMD} rpm -q alinas-efc-1.2-3.x86_64 || exit 1
303+
host_cmd rpm -q alinas-efc-1.2-3.x86_64 || exit 1
308304
echo "starting aliyun-alinas-mount-watchdog"
309-
${HOST_CMD} systemctl start aliyun-alinas-mount-watchdog || exit 1
305+
host_cmd systemctl start aliyun-alinas-mount-watchdog || exit 1
310306
fi
311307
fi
312308

313309
# place it here to remove leftover from previous version
314-
rm -rf /host/etc/csi-tool/*.{rpm,deb}
310+
rm -rf /host/etc/csi-tool/*.rpm /host/etc/csi-tool/*.deb

0 commit comments

Comments
 (0)