@@ -62,9 +62,7 @@ func BuildDistrolessContainer(ctx context.Context, input BuildDistrolessContaine
6262 }
6363 if bi != nil {
6464 baseImg = bi .ToState (input .SOpt , opts ... )
65- }
66-
67- if bi == nil {
65+ } else {
6866 baseImg = baseImg .File (llb .Mkdir ("/etc" , 0o755 ), opts ... ).
6967 File (llb .Mkdir ("/etc/apt" , 0o755 ), opts ... ).
7068 File (llb .Mkdir ("/etc/apt/apt.conf.d" , 0o755 ), opts ... ).
@@ -86,71 +84,74 @@ rootfs=/tmp/rootfs
8684apt_archives=/var/cache/apt/archives
8785
8886# Ensure apt cache directory exists
89- mkdir -p "$apt_archives"
87+ mkdir -p "${ apt_archives} "
9088
9189apt-get update
9290
9391essential_packages=$(dpkg-query -Wf '${Package} ${Essential}\n' | awk '$2 == "yes" {print $1}')
9492local_package_files=$(ls /base-packages/*.deb /spec-packages/*.deb)
9593
9694# Extract dependencies of local packages for downloading.
97- local_packages_dependencies=$(for f in $local_package_files; do dpkg-deb -f "$f " Depends 2>/dev/null; done | tr ',' '\n' | sed 's/([^)]*)//g; s/|.*//; s/ //g' | grep -v '^$' | sort -u)
95+ local_packages_dependencies=$(for f in ${ local_package_files} ; do dpkg-deb -f "${f} " Depends 2>/dev/null; done | tr ',' '\n' | sed 's/([^)]*)//g; s/|.*//; s/ //g' | grep -v '^$' | sort -u)
9896
9997# Get names of local packages so we can exclude them from apt-get install.
100- local_package_names=$(for f in $local_package_files; do dpkg-deb -f "$f " Package 2>/dev/null; done | sort -u)
98+ local_package_names=$(for f in ${ local_package_files} ; do dpkg-deb -f "${f} " Package 2>/dev/null; done | sort -u)
10199
102100# Spec packages may depend on base packages, so we need to filter to only download remaining packages, since downloading local packages
103101# would fail.
104- dependencies_to_download=$(echo "$local_packages_dependencies" | grep -vxF "$local_package_names")
102+ dependencies_to_download=$(echo "${ local_packages_dependencies} " | grep -vxF "${ local_package_names} ")
105103
106- # Use empty state file so we download all packages.
107- apt-get -o Dir::State::status="$rootfs/var/lib/dpkg/status" \
108- --yes --download-only install $essential_packages $dependencies_to_download
104+ # Use state file from target image so we only download necessary packages. If target image is a base image, less packages should
105+ # be downloaded.
106+ apt-get -o Dir::State::status="${rootfs}/var/lib/dpkg/status" \
107+ --yes --download-only install ${essential_packages} ${dependencies_to_download}
109108
110109# Extract all packages into the target rootfs.
111110#
112111# Extract base-files first to establish merged-usr symlinks (/bin -> usr/bin, etc.)
113112# before other packages create those paths as real directories, which would
114113# cause tar to fail when base-files tries to create the symlinks later.
115- base_files_package=$(ls "$apt_archives"/base-files_*.deb)
116- for f in $base_files_package $ local_package_files $(ls "$apt_archives"/*.deb | grep -vxF "$base_files_package"); do
117- dpkg-deb --extract "$f " "$rootfs"
114+ base_files_package=$(ls "${ apt_archives} "/base-files_*.deb)
115+ for f in ${ base_files_package} ${ local_package_files} $(ls "${ apt_archives} "/*.deb | grep -vxF "${ base_files_package} "); do
116+ dpkg-deb --extract "${f} " "${ rootfs} "
118117done
119118
120119# Fix merged-usr: on Noble+, /bin, /sbin, /lib should be symlinks to usr/bin, usr/sbin, usr/lib
121120# but dpkg-deb --extract may recreate them as real directories.
122121for dir in bin sbin lib; do
123- if [ -d "$rootfs/usr/$dir" ] && [ -d "$rootfs/$ dir" ] && [ ! -L "$rootfs/$ dir" ]; then
124- cp -a "$rootfs/$ dir"/* "$rootfs/usr/$dir/" 2>/dev/null || true
125- rm -rf "$rootfs/$ dir"
126- ln -s "usr/$dir" "$rootfs/$ dir"
122+ if [ -d "${ rootfs} /usr/${ dir} " ] && [ -d "${ rootfs}/${ dir} " ] && [ ! -L "${ rootfs}/${ dir} " ]; then
123+ cp -a "${ rootfs}/${ dir} "/* "${ rootfs} /usr/${ dir} /" 2>/dev/null || true
124+ rm -rf "${ rootfs}/${ dir} "
125+ ln -s "usr/${ dir} " "${ rootfs}/${ dir} "
127126 fi
128127done
129128
130129# dpkg-deb --extract doesn't run postinst scripts, so the /bin/sh symlink
131130# normally created by update-alternatives is missing. Create it manually.
132- if [ ! -e "$rootfs/usr/bin/sh" ] && [ ! -e "$rootfs/bin/sh" ]; then
133- ln -s dash "$rootfs/usr/bin/sh"
131+ if [ ! -e "${ rootfs} /usr/bin/sh" ] && [ ! -e "${ rootfs} /bin/sh" ]; then
132+ ln -s dash "${ rootfs} /usr/bin/sh"
134133fi
135134
136135# Remove usrmerge package - our merged-usr fixup above already handles this,
137136# and usrmerge's postinst fails on overlayfs (which BuildKit uses).
138137# Create a fake dpkg status entry so dpkg thinks it's installed.
139- for f in $(ls "$apt_archives"/usrmerge_*.deb "$apt_archives"/usr-is-merged_*.deb 2>/dev/null); do
140- pkg=$(dpkg-deb -f "$f" Package)
141- ver=$(dpkg-deb -f "$f" Version)
142- arch=$(dpkg-deb -f "$f" Architecture)
143- printf 'Package: %s\nStatus: install ok installed\nVersion: %s\nArchitecture: %s\nDescription: faked by dalec\n\n' "$pkg" "$ver" "$arch" >> "$rootfs/var/lib/dpkg/status"
144- rm "$f"
138+ #
139+ # This only runs when usrmerge package is not installed in the base image, since only then the deb file will be downloaded.
140+ for f in $(ls "${apt_archives}"/usrmerge_*.deb "${apt_archives}"/usr-is-merged_*.deb 2>/dev/null); do
141+ pkg=$(dpkg-deb -f "${f}" Package)
142+ ver=$(dpkg-deb -f "${f}" Version)
143+ arch=$(dpkg-deb -f "${f}" Architecture)
144+ printf 'Package: %s\nStatus: install ok installed\nVersion: %s\nArchitecture: %s\nDescription: faked by dalec\n\n' "${pkg}" "${ver}" "${arch}" >> "${rootfs}/var/lib/dpkg/status"
145+ rm "${f}"
145146done
146147
147- cp $local_package_files "$apt_archives"/*.deb "$rootfs$ apt_archives"/
148+ cp ${ local_package_files} "${ apt_archives} "/*.deb "${ rootfs}${ apt_archives} "/
148149
149150# Copy apt sources from worker into rootfs so the final container can install packages. Do we want that?
150151# There is no guarantee that the final image will have access to the same sources worker had (e.g. with mounted repos).
151152#
152153# A the moment this is necessary so we can for example install test dependencies without using worker image.
153- cp -ar /etc/apt/sources.list* "$rootfs/etc/apt/"
154+ cp -ar /etc/apt/sources.list* "${ rootfs} /etc/apt/"
154155`
155156
156157 script := llb .Scratch ().File (llb .Mkfile ("install.sh" , 0o755 , []byte (installScript )), opts ... )
0 commit comments