summaryrefslogtreecommitdiffstats
path: root/inst
diff options
context:
space:
mode:
Diffstat (limited to 'inst')
-rwxr-xr-xinst465
1 files changed, 465 insertions, 0 deletions
diff --git a/inst b/inst
new file mode 100755
index 0000000..44e17a5
--- /dev/null
+++ b/inst
@@ -0,0 +1,465 @@
+#!/bin/sh
+
+set -u
+
+host=
+dev=
+target=
+
+err()
+{
+ local fmt="${1}"
+ shift 1
+
+ printf "Error: ${fmt}\n" "${@}" 1>&3
+}
+
+info()
+{
+ local fmt="${1}"
+ shift 1
+
+ printf "${fmt}\n" "${@}" 1>&3
+}
+
+in_target()
+{
+ chroot "${target}" "${@}" || return 1
+
+ return 0
+}
+
+do_()
+{
+ step="${1}"
+ shift 1
+
+ do_${step} 1>&4 2>&4
+}
+
+do_fdisk()
+{
+ local script=
+ local line=
+
+ info 'Making partition table'
+
+ script=
+ while read line; do
+ script="$(printf '%s\n' "${script}" "${line}")"
+ done <<-EOF
+ ${part_script}
+ EOF
+ printf '%s\n' "${script}" | sfdisk "${dev}"
+
+ return 0
+}
+
+do_mkfs()
+{
+ local fs=
+ local mp=
+ local type=
+ local options=
+ local dump=
+ local pass=
+
+ info 'Making file systems'
+
+ while read fs mp type options dump pass; do
+ case "${type}" in ''|'swap') continue;; esac
+ case "${fs}" in
+ '@DEV'*'@')
+ fs="${fs%@}"
+ fs="${fs#@DEV}"
+ fs="${dev}${fs}"
+ ;;
+ *)
+ continue
+ ;;
+ esac
+ mkfs -t "${type}" "${fs}" || return 1
+ done <<-EOF
+ ${fstab}
+ EOF
+
+ return 0
+}
+
+do_mount()
+{
+ local fs=
+ local mp=
+ local type=
+ local options=
+ local dump=
+ local pass=
+
+ info 'Mounting file systems'
+
+ target="$(mktemp -d)"
+
+ while read fs mp type options dump pass; do
+ case "${type}" in ''|'swap') continue;; esac
+ case "${fs}" in
+ '@DEV'*'@')
+ fs="${fs%@}"
+ fs="${fs#@DEV}"
+ fs="${dev}${fs}"
+ ;;
+ *)
+ continue
+ ;;
+ esac
+ mkdir -p "${target}${mp}" || return 1
+ mount -t "${type}" ${options:+-o "${options}"} \
+ "${fs}" "${target}${mp}" || return 1
+ done <<-EOF
+ ${fstab}
+ EOF
+
+ return 0
+}
+
+do_check_target()
+{
+ if [ -e "${target}/bin/sh" ]; then
+ err 'Unclean target'
+ return 1
+ fi
+
+ return 0
+}
+
+do_debootstrap()
+{
+ local include=
+
+ info 'Installing base system'
+
+ case "${extra_pkgs}" in ?*)
+ include="--include=$(printf '%s,' ${extra_pkgs})"
+ include="${include%,}"
+ ;; esac
+
+ debootstrap --arch="${arch}" "${include}" \
+ "${suite}" "${target}" "${mirror}" || return 1
+
+ return 0
+}
+
+do_chroot_setup()
+{
+ info 'Setting up system'
+
+ case "$(uname -s)" in
+ 'Linux')
+ mount -t proc proc "${target}/proc" || return 1
+ mount -t sysfs sysfs "${target}/sys" || return 1
+ mount --bind /dev "${target}/dev" || return 1
+ mkdir -p "${target}/dev/pts" || return 1
+ mount -t devpts -o noexec,nosuid,gid=5,mode=620 \
+ devpts "${target}/dev/pts" || return 1
+ mount --bind /run "${target}/run" || return 1
+ ;;
+ esac
+
+ cat >"${target}/usr/sbin/policy-rc.d" <<-EOF
+ #!/bin/sh
+ exit 101
+ EOF
+ chmod a+rx "${target}/usr/sbin/policy-rc.d" || return 1
+
+ if [ -e "${target}/sbin/start-stop-daemon" ]; then
+ in_target dpkg-divert --quiet --add \
+ --divert '/sbin/start-stop-daemon.REAL' \
+ --rename '/sbin/start-stop-daemon' || return 1
+ fi
+ cat >"${target}/sbin/start-stop-daemon" <<-EOF
+ #!/bin/sh
+ exit 0
+ EOF
+ chmod a+rx "${target}/sbin/start-stop-daemon" || return 1
+
+ for file in /etc/network/interfaces /etc/networks /etc/hostname \
+ /etc/resolv.conf /etc/hosts; do
+ if ! [ -f "${file}" ]; then
+ continue
+ fi
+ if [ -f "${target}${file}" ]; then
+ mv "${target}${file}" "${target}${file}.REAL"
+ fi
+ mkdir -p "${target}${file%/*}"
+ cp "${file}" "${target}${file}"
+ done
+
+ export LANG="${locale}"
+ export PERL_BADLANG=0
+ export DEBCONF_ADMIN_EMAIL=''
+ export IT_LANG_OVERRIDE='C'
+ export APT_LISTCHANGES_FRONTEND='none'
+ export SUDO_FORCE_REMOVE='yes'
+
+ return 0
+}
+
+do_fstab_setup()
+{
+ local fs=
+ local mp=
+ local type=
+ local options=
+ local dump=
+ local pass=
+
+ info 'Making file system table'
+
+ case "$(uname -s)" in
+ 'Linux')
+ printf '%-15s %-15s %-7s %-15s %-7s %s\n' \
+ 'proc' '/proc' 'proc' 'defaults' '0' '0' \
+ >"${target}/etc/fstab"
+ ;;
+ esac
+ while read fs mp type options dump pass; do
+ case "${fs}" in '@DEV'*'@')
+ fs="${fs%@}"
+ fs="${fs#@DEV}"
+ fs="${dev}${fs}"
+ fs="UUID=$(blkid -o value -s UUID "${fs}")"
+ ;; esac
+ printf '%-15s %-15s %-7s %-15s %-7s %s\n' \
+ "${fs}" "${mp}" "${type}" "${options}" \
+ "${dump}" "${pass}" >>"${target}/etc/fstab"
+ done <<-EOF
+ ${fstab}
+ EOF
+}
+
+do_apt_update()
+{
+ info 'Downloading package lists'
+
+ in_target apt-get update || return 1
+
+ return 0
+}
+
+do_locale_setup()
+{
+ local l=
+ local gen=
+
+ info 'Setting locale'
+
+ if ! [ "x${locale}" = 'xC' ] || ! [ "x${supported_locales}" = 'x' ]
+ then
+ in_target apt-get -q -y install locales
+
+ gen=false
+ for l in $(printf '%s\n' "${locale}" ${supported_locales} | \
+ sort -u); do
+ if ! LANG=C in_target validlocale "${l}" \
+ >>"${target}/etc/locale.gen" 2>/dev/null
+ then
+ gen=true
+ fi
+ done
+ if ${gen}; then
+ in_target locale-gen --keep-existing >/dev/null || \
+ return 1
+ fi
+ fi
+
+ printf 'LANG=%s\n' "${locale}" >"${target}/etc/default/locale"
+}
+
+do_tz_setup()
+{
+ info 'Setting time zone'
+
+ if [ "x${time_zone}" = 'x' ] || ! [ -e \
+ "${target}/usr/share/zoneinfo/${time_zone}" ]; then
+ err '%s: Invalid time zone' "${time_zone}"
+ return 1
+ fi
+
+ printf '%s\n' "${time_zone}" >"${target}/etc/timezone"
+ cp -f "${target}/usr/share/zoneinfo/${time_zone}" \
+ "${target}/etc/localtime"
+}
+
+do_user_setup()
+{
+ local group=
+ local f=
+
+ info 'Setting users and passwords'
+
+ in_target shadowconfig "${passwd_shadow}" || return 1
+
+ case "${root_passwd_crypted}" in ?*)
+ in_target usermod --password="${root_passwd_crypted}" 'root' \
+ || return 1
+ ;; esac
+
+ if ${user_make}; then
+ in_target adduser --disabled-password \
+ --gecos "${user_full_name}" \
+ "${user_name}" || return 1
+ in_target usermod --password="${user_passwd_crypted}" \
+ "${user_name}" || return 1
+ in_target chown "${user_name}:${user_name}" \
+ "/home/${user_name}" || return 1
+ if ! ${root_login}; then
+ in_target apt-get -q -y install sudo || return 1
+ case " ${user_groups} " in
+ *' sudo '*);;
+ *)
+ user_groups="${user_groups} sudo"
+ ;;
+ esac
+ if in_target update-alternatives \
+ --display libgksu-gconf-defaults \
+ 1>/dev/null 2>&1; then
+ f='/usr/share/libgksu/debian'
+ f="${f}/gconf-defaults.libgksu-sudo"
+ in_target update-alternatives \
+ --set libgksu-gconf-defaults "${f}" || \
+ return 1
+ in_target update-gconf-defaults
+ fi
+ printf 'Aptitude::Get-Root-Command "%s";' \
+ 'sudo:/usr/bin/sudo' \
+ >"${target}/etc/apt/apt.conf.d/00aptitude"
+ fi
+ for group in ${user_groups}; do
+ in_target adduser "${user_name}" "${group}" || return 1
+ done
+ fi
+}
+
+do_install_extra()
+{
+ info 'Installing extra packages'
+
+ in_target apt-get -q -y install ${postinst_pkgs} || return 1
+
+ return 0
+}
+
+do_chroot_cleanup()
+{
+ local mp=
+
+ info 'Cleaning up system'
+
+ for file in /etc/network/interfaces /etc/networks /etc/hostname \
+ /etc/resolv.conf /etc/hosts; do
+ if [ -f "${target}${file}.REAL" ]; then
+ mv "${target}${file}.REAL" "${target}${file}"
+ fi
+ done
+
+ rm -f "${target}/usr/sbin/policy-rc.d"
+ rm -f "${target}/sbin/start-stop-daemon"
+ in_target dpkg-divert --quiet --remove \
+ --rename '/sbin/start-stop-daemon' || return 1
+
+ case "$(uname -s)" in
+ 'Linux')
+ for mp in 'run' 'dev/pts' 'dev' 'sys' 'proc'; do
+ while ! umount "${target}/${mp}"; do
+ sleep 1
+ done
+ done
+ ;;
+ esac
+
+ return 0
+}
+
+do_umount()
+{
+ local fs=
+ local mp=
+ local type=
+ local options=
+ local dump=
+ local pass=
+
+ info 'Unmounting file systems'
+
+ while read fs mp type options dump pass; do
+ case "${type}" in ''|'swap') continue;; esac
+ case "${fs}" in
+ '@DEV'*'@')
+ ;;
+ *)
+ continue
+ ;;
+ esac
+ while ! umount "${target}${mp}"; do
+ sleep 1
+ done
+ rmdir "${target}${mp}"
+ done <<-EOF
+ ${fstab}
+ EOF
+
+ return 0
+}
+
+usage()
+{
+ printf 'Usage: %s host device\n' "${0}"
+}
+
+main()
+{
+ local host_file=
+ local log=
+
+ exec 3>&1
+
+ if [ ${#} -ne 2 ]; then
+ usage >&2
+ return 1
+ fi
+ host="${1}"
+ host_file="$(dirname "${0}")/hosts/${host}"
+ if ! [ -r "${host_file}" ]; then
+ err '%s: Unknown host' "${host}"
+ return 1
+ fi
+ dev="${2}"
+
+ . "${host_file}"
+
+ log="$(mktemp)"
+ exec 4>"${log}"
+ do_ fdisk || return 1
+ do_ mkfs || return 1
+ do_ mount || return 1
+ do_ check_target || { do_ umount; return 1; }
+ do_ debootstrap || { do_ umount; return 1; }
+ do_ chroot_setup || { do_ umount; return 1; }
+ do_ fstab_setup || { do_ chroot_cleanup; do_ umount; return 1; }
+ do_ apt_update || { do_ chroot_cleanup; do_ umount; return 1; }
+ do_ locale_setup || { do_ chroot_cleanup; do_ umount; return 1; }
+ do_ tz_setup || { do_ chroot_cleanup; do_ umount; return 1; }
+ do_ user_setup || { do_ chroot_cleanup; do_ umount; return 1; }
+ do_ install_extra || { do_ chroot_cleanup; do_ umount; return 1; }
+ postinst || { do_ chroot_cleanup; do_ umount; return 1; }
+ do_ chroot_cleanup || { do_ umount; return 1; }
+ exec 4>&-
+ mkdir -p "${target}/var/log/installer"
+ mv "${log}" "${target}/var/log/installer/log"
+ do_umount || return 1
+
+ exec 3>&-
+
+ return 0
+}
+
+main "${@}"