2019-02-24 10:07:31 +01:00
|
|
|
#!/usr/bin/env bash
|
2019-12-21 23:06:33 +00:00
|
|
|
set -x
|
|
|
|
#
|
|
|
|
# Script to create Rosa Linux base images for integration with VM containers (docker, lxc , etc.).
|
|
|
|
#
|
|
|
|
# Based on mkimage-urpmi.sh (https://github.com/juanluisbaptiste/docker-brew-mageia)
|
2019-02-24 10:07:31 +01:00
|
|
|
#
|
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
set -efu
|
2019-02-24 10:07:31 +01:00
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
if [ "$(id -u)" != "0" ]; then
|
|
|
|
echo "Please run as root. Example: sudo ./mkimage-urpmi.sh"
|
2019-02-24 10:07:31 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
arch="${arch:-x86_64}"
|
|
|
|
imgType="${imgType:-min}"
|
|
|
|
rosaVersion="${rosaVersion:-rosa2016.1}"
|
|
|
|
outDir="${outDir:-"."}"
|
|
|
|
packagesList="${packagesList:-basesystem-minimal urpmi bash vim-minimal termcap initscripts systemd}"
|
|
|
|
addPackages="${addPackages:-""}"
|
|
|
|
# Example: addRepos="repoName1;http://repo.url/ repoName2;http://repo.url/"
|
|
|
|
addRepos="${addRepos:-""}"
|
|
|
|
brandingPackages="${brandingPackages:-branding-configs-fresh}"
|
|
|
|
if [ -n "$addPackages" ]; then packagesList="${packagesList} ${addPackages}"; fi
|
|
|
|
if [ -n "$brandingPackages" ]; then packagesList="${packagesList} ${brandingPackages}"; fi
|
|
|
|
mirror="${mirror:-http://abf-downloads.rosalinux.ru/}"
|
|
|
|
repo="${repo:-${mirror}/${rosaVersion}/repository/${arch}/}"
|
|
|
|
outName="${outName:-"rootfs-${imgType}-${rosaVersion}_${arch}_$(date +%Y-%m-%d)"}"
|
|
|
|
rootfsDir="${rootfsDir:-./BUILD_${outName}}"
|
|
|
|
tarFile="${outName}.tar.xz"
|
|
|
|
sqfsFile="${outName}.sqfs"
|
|
|
|
systemd_networkd="${systemd_networkd:-1}"
|
|
|
|
rootfsPackTarball="${rootfsPackTarball:-1}"
|
|
|
|
rootfsPackSquash="${rootfsPackSquash:-1}"
|
|
|
|
rootfsXzCompressLevel="${rootfsXzCompressLevel:-6}"
|
|
|
|
rootfsXzThreads="${rootfsXzThreads:-0}"
|
|
|
|
rootfsSquashCompressAlgo="${rootfsSquashCompressAlgo:-xz}"
|
|
|
|
rootfsSquashBlockSize="${rootfsSquashBlockSize:-512K}"
|
|
|
|
clean_rootfsDir="${clean_rootfsDir:-1}"
|
|
|
|
|
|
|
|
# Ensure that rootfsDir from previous build will not be reused
|
|
|
|
if [ "$clean_rootfsDir" = 1 ]; then
|
|
|
|
umount "${rootfsDir}/dev" || :
|
|
|
|
rm -fr "$rootfsDir"
|
2019-02-24 10:07:31 +01:00
|
|
|
fi
|
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
urpmi.addmedia --distrib \
|
|
|
|
--mirrorlist "$repo" \
|
|
|
|
--urpmi-root "$rootfsDir"
|
|
|
|
|
|
|
|
if [ -n "$addRepos" ]; then
|
|
|
|
while read -r line
|
|
|
|
do
|
|
|
|
repoName="$(echo "$line" | awk -F ';' '{print $1}')"
|
|
|
|
repoUrl="$(echo "$line" | awk -F ';' '{print $2}')"
|
|
|
|
if [ -z "$repoName" ] || [ -z "$repoUrl" ]; then
|
|
|
|
echo "Incorrect repository line ${line}, use a correct form: repoName;http://repo.url/"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
urpmi.addmedia \
|
|
|
|
--urpmi-root "$rootfsDir" \
|
|
|
|
"$repoName" "$repoUrl"
|
|
|
|
unset repoName repoUrl
|
|
|
|
done <<< "$(echo "$addRepos" | tr ' ' '\n')"
|
2019-02-24 10:07:31 +01:00
|
|
|
fi
|
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
#########################################################
|
|
|
|
# try to workaround urpmi bug due to which it randomly
|
|
|
|
# can't resolve dependencies during bootstrap
|
|
|
|
urpmi_bootstrap(){
|
|
|
|
for urpmi_options in \
|
|
|
|
"--auto --no-suggests --allow-force --allow-nodeps --ignore-missing" \
|
|
|
|
"--auto --no-suggests"
|
|
|
|
do
|
|
|
|
urpmi --urpmi-root "$rootfsDir" \
|
|
|
|
${urpmi_options} \
|
|
|
|
${packagesList}
|
|
|
|
urpmi_return_code="$?"
|
|
|
|
done
|
2019-02-24 10:07:31 +01:00
|
|
|
}
|
2019-12-21 23:06:33 +00:00
|
|
|
# temporarily don't fail the whole scripts when not last iteration of urpmi fails
|
|
|
|
set +e
|
|
|
|
for i in $(seq 1 10)
|
|
|
|
do
|
|
|
|
urpmi_bootstrap
|
|
|
|
if [ "${urpmi_return_code}" = 0 ]; then
|
|
|
|
echo "urpmi iteration #${i} was successfull."
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
# now check the return code of the _last_ urpmi iteration
|
|
|
|
if [ "${urpmi_return_code}" != 0 ]; then
|
|
|
|
echo "urpmi bootstrapping failed!"
|
|
|
|
exit 1
|
2019-02-24 10:07:31 +01:00
|
|
|
fi
|
2019-12-21 23:06:33 +00:00
|
|
|
# return failing the whole script on any error
|
|
|
|
set -e
|
|
|
|
#########################################################
|
|
|
|
|
|
|
|
pushd "$rootfsDir"
|
|
|
|
|
|
|
|
# Clean
|
|
|
|
# urpmi cache
|
|
|
|
rm -rf var/cache/urpmi
|
|
|
|
mkdir -p --mode=0755 var/cache/urpmi
|
|
|
|
rm -rf etc/ld.so.cache var/cache/ldconfig
|
|
|
|
mkdir -p --mode=0755 var/cache/ldconfig
|
|
|
|
popd
|
2019-02-24 10:07:31 +01:00
|
|
|
|
|
|
|
# make sure /etc/resolv.conf has something useful in it
|
2019-12-21 23:06:33 +00:00
|
|
|
mkdir -p "$rootfsDir/etc"
|
|
|
|
cat > "$rootfsDir/etc/resolv.conf" <<'EOF'
|
2019-02-24 10:07:31 +01:00
|
|
|
nameserver 8.8.8.8
|
2019-12-21 23:06:33 +00:00
|
|
|
nameserver 77.88.8.8
|
2019-02-24 10:07:31 +01:00
|
|
|
nameserver 8.8.4.4
|
2019-12-21 23:06:33 +00:00
|
|
|
nameserver 77.88.8.1
|
2019-02-24 10:07:31 +01:00
|
|
|
EOF
|
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
# Fix SSL in chroot (/dev/urandom is needed)
|
|
|
|
mount --bind -v -o ro /dev "${rootfsDir}/dev"
|
|
|
|
# Let's make sure that all packages have been installed
|
|
|
|
chroot "$rootfsDir" /bin/sh -c "urpmi ${packagesList} --auto --no-suggests --clean"
|
2019-02-24 10:07:31 +01:00
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
# clean-up
|
|
|
|
for i in dev sys proc; do
|
|
|
|
umount "${rootfsDir}/${i}" || :
|
|
|
|
rm -fr "${rootfsDir:?}/${i:?}/*"
|
|
|
|
done
|
2019-02-24 10:07:31 +01:00
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
# systemd-networkd makes basic network configuration automatically
|
|
|
|
# After it, you can either make /etc/systemd/network/*.conf or
|
|
|
|
# `systemctl enable dhclient@eth0`, where eth0 is your network interface from `ip a`
|
|
|
|
if [ "$systemd_networkd" != 0 ]; then
|
|
|
|
chroot "$rootfsDir" /bin/sh -c "systemctl enable systemd-networkd"
|
|
|
|
# network.service is generated by systemd-sysv-generator from /etc/rc.d/init.d/network
|
|
|
|
chroot "$rootfsDir" /bin/sh -c "systemctl mask network.service"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# disable pam_securetty to allow logging in as root via `systemd-nspawn -b`
|
|
|
|
# https://bugzilla.rosalinux.ru/show_bug.cgi?id=9631
|
|
|
|
# https://github.com/systemd/systemd/issues/852
|
|
|
|
if grep -q 'pam_securetty.so' "${rootfsDir}/etc/pam.d/login"; then
|
|
|
|
sed -e '/pam_securetty.so/d' -i "${rootfsDir}/etc/pam.d/login"
|
2019-02-24 10:07:31 +01:00
|
|
|
fi
|
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
( set -x
|
|
|
|
if [ "$rootfsPackTarball" != 0 ]; then
|
|
|
|
env XZ_OPT="-${rootfsXzCompressLevel} --threads=${rootfsXzThreads} -v" \
|
|
|
|
tar cJf "${outDir}/${tarFile}" --numeric-owner --transform='s,^./,,' --directory="$rootfsDir" .
|
|
|
|
ln -sf "$tarFile" "./rootfs.tar.xz" || :
|
|
|
|
fi
|
|
|
|
if [ "$rootfsPackSquash" != 0 ]; then
|
|
|
|
mksquashfs "$rootfsDir" "${outDir}/${sqfsFile}" -comp "$rootfsSquashCompressAlgo" -b "$rootfsSquashBlockSize"
|
2019-02-24 10:07:31 +01:00
|
|
|
fi
|
|
|
|
|
2019-12-21 23:06:33 +00:00
|
|
|
rm -rf "$rootfsDir"
|
|
|
|
)
|