Last active
July 4, 2021 09:22
-
-
Save creatldd1/99db8d68e2a97e2737c5bb488be67328 to your computer and use it in GitHub Desktop.
Ifenslave issue when preinstalling it on Ubuntu 20.04 Offline Custom iso
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
PARAM_DEBUGON=${PARAM_DEBUGON:-true} | |
set -o errexit | |
set -o nounset | |
if [[ "${PARAM_DEBUGON}" == "true" ]]; then | |
set -x xtrace | |
set -o errtrace | |
set -o functrace | |
export PS4='+ $(basename ${BASH_SOURCE[0]}) Line ${LINENO}: ' # available in -x mode | |
fi | |
trap 'echo "+ $(basename ${BASH_SOURCE[0]:-""}) Line ${LINENO}" ERROR' ERR | |
# ---------------------------------------------------------------------------------- | |
# INTERNAL PARAMETERS | |
# ---------------------------------------------------------------------------------- | |
export _APTCACHER_DEFAULT_CONFIG=' | |
Acquire::http::Proxy "http://192.168.250.27:3142";} | |
//Bypass HTTPS repos | |
Acquire::http::Proxy { apt.releases.hashicorp.com DIRECT; }; | |
Acquire::http::Proxy { download.docker.com DIRECT; }; | |
Acquire::http::Proxy { deb.nodesource.com DIRECT; }; | |
Acquire::http::Proxy { packages.microsoft.com DIRECT; }; | |
Acquire::http::Proxy { packages.cloud.google.com DIRECT; }; | |
Acquire::http::Proxy { packagecloud.io DIRECT; }; | |
Acquire::http::Proxy { deb.opera.com DIRECT; }; | |
//Bypass some problematic repo | |
# Acquire::http::Proxy { security.ubuntu.com DIRECT; }; | |
' | |
export _APTCACHER_DEFAULT_CONFIG= | |
export _SOURCE_INSTALLER="old_iso/casper/installer.squashfs" | |
export _SOURCE_FILESYSTEM="old_iso/casper/filesystem.squashfs" | |
_TMP_ROOTDIR=$( readlink -f "./tmp") | |
export MDD_CHROOT="" # chroot cmd like "chroot <rootfs dir>" | |
export MDD_TARGET_DIR="" # rootfs dir | |
# ---------------------------------------------------------------------------------- | |
# PARAMETERS | |
# ---------------------------------------------------------------------------------- | |
export PARAM_PREINSTALL_PACKAGES=${PARAM_PREINSTALL_PACKAGES:-"true"} # live install ? | |
export PARAM_APT_PROXYCONFIG=${PARAM_APT_PROXYCONFIG:-"$_APTCACHER_DEFAULT_CONFIG"} | |
export PARAM_PACKAGES=${PARAM_PACKAGES:-ifenslave} # packages to install on target | |
export PARAM_OLD_ISO=${PARAM_OLD_ISO:-"$(readlink -f ./ubuntu-20.04.2-live-server-amd64.iso)"} | |
export PARAM_NEW_ISO=${PARAM_NEW_ISO:-"./customIsoTest_ubuntu-20.04.2-live-server-amd64.iso"} | |
# ---------------------------------------------------------------------------------- | |
# FUNCTIONS | |
# ---------------------------------------------------------------------------------- | |
_MOUNTS=() | |
do_createTmpDir() | |
{ | |
local argDirNamePrefix="$1" | |
# local tmpdir="$(mktemp --directory --tmpdir="${_TMP_ROOTDIR}" "${argDirNamePrefix}_XXXXX")" # FIXME : doesn't work | |
local tmpdir="${_TMP_ROOTDIR}/${argDirNamePrefix}_$(date +%s%3N)" | |
mkdir -p ${tmpdir} | |
if [[ ! -d "${tmpdir}" ]]; then | |
return 1 | |
fi | |
echo "${tmpdir}" | |
return 0 | |
} | |
do_mount_existing() | |
{ | |
local mountpoint="${!#}" | |
mount "$@" | |
_MOUNTS=( "${mountpoint}" "${_MOUNTS[@]:+"${_MOUNTS[@]}"}" ) | |
} | |
do_mount() | |
{ | |
local mountpoint="${!#}" | |
mkdir -p "${mountpoint}" | |
do_mount_existing "$@" | |
} | |
undo_mount() { | |
echo "FS to unmount ${_MOUNTS[@]}" | |
for i in ${!_MOUNTS[@]}; # number of retries | |
do | |
local retry="false" | |
local failed=() | |
for m in "${_MOUNTS[@]:+"${_MOUNTS[@]}"}"; do | |
echo "Trying to unmount ${m}" | |
if grep --quiet --no-messages $(readlink -f ${m}) /proc/mounts; then | |
umount "${m}" || ( echo "Unmount failed for ${m}. Will retry later"; retry="true") | |
sleep 1 | |
else | |
echo "Skipping ${m}. Not mounted." | |
fi | |
done | |
[[ "$retry" == "false" ]] && break | |
done | |
_MOUNTS=() | |
return 0 | |
} | |
add_overlay() | |
{ | |
local lower="$1" | |
local mountpoint="$2" | |
local work=$(do_createTmpDir "overlaywork_${lower//[ ;:,\\]_}") | |
if [ -n "${3-}" ]; then | |
local upper="${3}" | |
else | |
local upper="$(do_createTmpDir "overlayup_${lower//[ ;:,\\]_}")" | |
fi | |
if ! [[ -d "${work}" && -d "${upper}" ]]; then | |
return 1 | |
fi | |
chmod go+rx "${work}" "${upper}" | |
do_mount -t overlay overlay -o lowerdir="${lower}",upperdir="${upper}",workdir="${work}" "${mountpoint}" | |
} | |
prepare_rootfs() | |
{ | |
if [[ ! ( -n "$MDD_TARGET_DIR" && -d "$MDD_TARGET_DIR" ) || -z $MDD_CHROOT ]]; then # check | |
return 1 | |
fi | |
# configure the rootfs | |
# Change policy to not start daemons | |
echo "#!/bin/sh | |
exit 101" > ${MDD_TARGET_DIR}/usr/sbin/policy-rc.d | |
chmod a+x ${MDD_TARGET_DIR}/usr/sbin/policy-rc.d | |
if [[ "${#PARAM_APT_PROXYCONFIG}" != "0" ]]; then | |
echo "$PARAM_APT_PROXYCONFIG" > ${MDD_TARGET_DIR}/etc/apt/apt.conf.d/01proxy | |
cat ${MDD_TARGET_DIR}/etc/apt/apt.conf.d/01proxy # check | |
fi | |
# prepare for chroot | |
do_mount_existing dev-live-fs -t devtmpfs "new_filesystem/dev" | |
do_mount devpts-live-fs -t devpts "new_filesystem/dev/pts" | |
do_mount_existing proc-live-fs -t proc "new_filesystem/proc" | |
do_mount_existing sysfs-live-fs -t sysfs "new_filesystem/sys" | |
do_mount_existing securityfs-live-fs -t securityfs "new_filesystem/sys/kernel/security" | |
# Network | |
# sudo cp /etc/resolv.conf new_filesystem/etc/resolv.conf | |
mv "${MDD_TARGET_DIR}/etc/resolv.conf" "${MDD_TARGET_DIR}/etc/resolv.conf.backup" | |
cp -f /etc/resolv.conf "${MDD_TARGET_DIR}/etc/resolv.conf" | |
[ -f "${MDD_TARGET_DIR}/etc/hosts" ] && mv "${MDD_TARGET_DIR}/etc/hosts" "${MDD_TARGET_DIR}/etc/hosts.backup" | |
cp -f /etc/hosts "${MDD_TARGET_DIR}/etc/hosts" | |
return 0 | |
} | |
clean_rootfs() | |
{ | |
if [[ -z "${MDD_CHROOT}" ]]; then | |
return 1 | |
fi | |
# Change policy to allow daemons to start | |
rm -f ${MDD_TARGET_DIR}/usr/sbin/policy-rc.d | |
# disable Apt Proxy | |
# if packages are not preinstalled (meaning online install) we keep the proxy config for debug purpose | |
if [[ "${PARAM_PREINSTALL_PACKAGES}" == "true" ]]; then | |
rm -f ${MDD_TARGET_DIR}/etc/apt/apt.conf.d/01proxy | |
fi | |
# Network | |
rm -f "${MDD_TARGET_DIR}/etc/resolv.conf" | |
mv "${MDD_TARGET_DIR}/etc/resolv.conf.backup" "${MDD_TARGET_DIR}/etc/resolv.conf" | |
rm -f "${MDD_TARGET_DIR}/etc/hosts" | |
mv "${MDD_TARGET_DIR}/etc/hosts.backup" "${MDD_TARGET_DIR}/etc/hosts" | |
# do_mounts are automatically undone upon shell exit | |
} | |
function main() | |
{ | |
_MOUNTS=() | |
trap undo_mount EXIT | |
# raz | |
sudo rm -rf "${_TMP_ROOTDIR}" | |
mkdir -p "${_TMP_ROOTDIR}" | |
chmod ugo+rwx "${_TMP_ROOTDIR}" | |
cd "${_TMP_ROOTDIR}" | |
# --------------------- | |
# Mount the iso | |
# --------------------- | |
do_mount -t iso9660 -o loop,ro "${PARAM_OLD_ISO}" old_iso | |
# do_mount -t squashfs ${_SOURCE_FILESYSTEM} old_filesystem | |
argLower="old_iso" | |
argMountpoint="new_iso" | |
argUpper= | |
add_overlay "$argLower" "$argMountpoint" "$argUpper" | |
# --------------------- | |
# AUTOINSTALL / CLOUD INIT | |
# --------------------- | |
mkdir --parents new_iso/nocloud/ | |
touch new_iso/nocloud/meta-data | |
cat > new_iso/nocloud/user-data << 'EOF' | |
#cloud-config | |
autoinstall: | |
version: 1 | |
interactive-sections: | |
- network | |
- locale | |
keyboard: {layout: fr, toggle: toggle, variant: ""} | |
identity: | |
hostname: customhostname | |
username: user1 | |
password: "__USER1_PASSWORD__" | |
ssh: | |
allow-pw: true | |
install-server: yes | |
late-commands: | |
- curtin in-target --target=/target -- timedatectl set-timezone UTC | |
- curtin in-target --target=/target -- timedatectl set-ntp true | |
- curtin in-target --target=/target -- apt-get --purge -y --quiet=2 autoremove | |
- curtin in-target --target=/target -- apt-get clean | |
EOF | |
sed --in-place "s@__USER1_PASSWORD__@$(echo "password1"|mkpasswd -m sha-512 --stdin)@g" new_iso/nocloud/user-data | |
# Update boot flags with cloud-init autoinstall: | |
## Should look similar to this: initrd=/casper/initrd quiet autoinstall ds=nocloud;s=/cdrom/nocloud/ --- | |
sed -i 's|---|autoinstall ds=nocloud\\\;s=/cdrom/nocloud/ ---|g' new_iso/boot/grub/grub.cfg | |
sed -i 's|---|autoinstall ds=nocloud;s=/cdrom/nocloud/ ---|g' new_iso/isolinux/txt.cfg | |
# --------------------- | |
# INSTALL PACKAGES | |
# --------------------- | |
if true; then | |
# mount iso/filesystem.squashfs | |
do_mount -t squashfs ${_SOURCE_FILESYSTEM} old_filesystem | |
# create an overlay over it to register the changes | |
argLower="old_filesystem" | |
argMountpoint="new_filesystem" | |
argUpper="upper_filesystem" | |
mkdir -p "$argUpper" | |
add_overlay "$argLower" "$argMountpoint" "$argUpper" | |
export MDD_CHROOT="chroot new_filesystem" | |
export MDD_TARGET_DIR="$argMountpoint" | |
# Pre-install some packages ? | |
( | |
_MOUNTS=() | |
trap undo_mount EXIT # clean any mounted fs in this block upon exiting this block | |
prepare_rootfs | |
if [ "${PARAM_PREINSTALL_PACKAGES}" == "true" ]; then | |
set +o nounset # nounset is problematic with the use of <<EOF | |
${MDD_CHROOT} bash -x <<'EOF' | |
set -o errexit # exit on sight of the first error | |
env | |
export DEBIAN_FRONTEND=noninteractive | |
export DEBCONF_NONINTERACTIVE_SEEN=true | |
export LC_ALL=C | |
export HOME=/root | |
apt-get update | |
apt-get dist-upgrade -y | |
apt install -y -f ${PARAM_PACKAGES} | |
apt-get dist-upgrade -y | |
# Clean apt | |
apt-get -y clean | |
apt-get -y autoremove --purge -y | |
apt-get -y autoclean | |
apt-get check | |
EOF | |
set -o nounset | |
fi | |
clean_rootfs | |
# Compute filesystem manifest. | |
${MDD_CHROOT} dpkg-query -W --showformat='${Package} ${Version}\n' > new_iso/casper/filesystem.manifest | |
) | |
rm new_iso/casper/filesystem.squashfs | |
mksquashfs new_filesystem new_iso/casper/filesystem.squashfs | |
fi | |
# update md5 | |
( | |
# Disable mandatory md5 checksum on boot: | |
md5sum new_iso/.disk/info > new_iso/md5sum.txt | |
sed -i 's|new_iso/|./|g' new_iso/md5sum.txt | |
# FIXME : restore computation of md5 | |
) | |
# rebuild iso | |
( | |
opts="$(xorriso -indev ${PARAM_OLD_ISO} -report_el_torito as_mkisofs)" | |
echo "xorriso options : $opts" | |
eval set -- ${opts} | |
xorriso -as mkisofs "$@" -o ${PARAM_NEW_ISO} -V LDE_Ubuntu new_iso | |
) | |
} | |
# ---------------------------------------------------------------------------------- | |
# M A I N | |
# ---------------------------------------------------------------------------------- | |
main | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment