summaryrefslogtreecommitdiffstats
path: root/lib/install.sh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/install.sh')
-rw-r--r--lib/install.sh274
1 files changed, 274 insertions, 0 deletions
diff --git a/lib/install.sh b/lib/install.sh
new file mode 100644
index 0000000..b7ca485
--- /dev/null
+++ b/lib/install.sh
@@ -0,0 +1,274 @@
+# Functions for installing systems
+#
+# Copyright (C) 2013, 2014 Patrick "P. J." McDermott
+#
+# This file is part of the ProteanOS Development Kit.
+#
+# The ProteanOS Development Kit is free software: you can redistribute
+# it and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# The ProteanOS Development Kit is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with the ProteanOS Development Kit. If not, see
+# <http://www.gnu.org/licenses/>.
+
+[ "x${_INSTALL_SM+set}" = 'xset' ] && return 0
+_INSTALL_SM=1
+
+use profile
+use dir
+use fd
+use pkg
+
+install_deps=
+install_fnames=
+install_md5sums=
+install_sha256sums=
+install_feed_url=
+
+install_system()
+{
+ local mirror="${1}"
+ local suite="${2}"
+ local arch="${3}"
+ local plat="${4}"
+ local chroot="${5}"
+ local foreign="${6}"
+
+ if [ "x${arch}" = 'x' ]; then
+ arch="$(profile_detect_arch)"
+ fi
+ if [ "x${plat}" = 'x' ]; then
+ plat="$(profile_default_plat)"
+ fi
+ if [ "x${mirror}" = 'x' ]; then
+ mirror="$(profile_select_mirror)"
+ fi
+
+ if ! profile_validate_archplat "${mirror}" "${arch}" "${plat}" \
+ "${suite}"; then
+ error 2 "$(get_msg 'install_bad_archplat')" \
+ "${arch}" "${plat}"
+ fi
+
+ info "$(get_msg 'install_selected_arch')" "${arch}"
+ info "$(get_msg 'install_selected_plat')" "${plat}"
+ info "$(get_msg 'install_selected_mirror')" "${mirror}"
+
+ info "$(get_msg 'install_setting_up_chroot')"
+ if [ -d "${chroot}" ] && ! dir_is_empty "${chroot}" 'lost+found'; then
+ error 2 "$(get_msg 'install_chroot_dir_exists')" "${chroot}"
+ fi
+ if ! mkdir -p "${chroot}/.prokit" "${chroot}/prokit"; then
+ error 2 "$(get_msg 'install_mkdir_chroot_fail')" "${chroot}"
+ fi
+ >"${chroot}/prokit/installing"
+
+ info "$(get_msg 'install_find_pkgs')"
+ install_find_pkgs "${mirror}" "${suite}" "${arch}" "${plat}" \
+ "${chroot}"
+ install_get_pkgs "${chroot}"
+
+ info "$(get_msg 'install_configuring')"
+ if ! ${foreign}; then
+ profile_configure_system_native "${chroot}" "${arch}" "${plat}"
+ else
+ profile_configure_system_foreign "${chroot}" "${arch}" "${plat}"
+ fi
+
+ rm "${chroot}/prokit/installing"
+}
+
+install_find_pkgs()
+{
+ local mirror="${1}"
+ local suite="${2}"
+ local arch="${3}"
+ local plat="${4}"
+ local chroot="${5}"
+ local opkg_conf_fd=
+ local pkgs_fd=
+ local opt=
+ local feed_idx=
+ local feed=
+ local gzip=
+ local pkgs=
+
+ mkdir -p "${chroot}/etc/opkg" "${chroot}/var/lib/opkg/lists"
+ fopen "${chroot}/etc/opkg/opkg.conf" 'w'
+ opkg_conf_fd=${FD}
+
+ install_deps=
+ install_fnames=
+ install_md5sums=
+ install_sha256sums=
+
+ fopen "${chroot}/.prokit/packages" 'w'
+ pkgs_fd=${FD}
+
+ while read -r opt feed_idx feed; do
+ case "${opt}" in
+ 'src') gzip=false;;
+ 'src/gz') gzip=true;;
+ *) continue;;
+ esac
+ printf '%s %s %s\n' "${opt}" "${feed_idx}" \
+ "${feed%/Packages*}" >&${opkg_conf_fd}
+ feed_download "${feed}" ${gzip} \
+ >"${chroot}/var/lib/opkg/lists/${feed_idx}"
+ install_feed_url="${feed%/*}"
+ feed_find_pkgs "${chroot}/var/lib/opkg/lists/${feed_idx}" \
+ "$(profile_dep_fields)" profile_include_pkg \
+ install_deps_cb install_fname_cb \
+ install_md5sum_cb install_sha256sum_cb \
+ >&${pkgs_fd}
+ done <<-EOF
+ $(profile_feeds "${mirror}" "${arch}" "${plat}" "${suite}")
+ EOF
+
+ printf '\ndest root /\n' >&${opkg_conf_fd}
+ printf 'arch %s 1\n' 'all' "${arch}" 'src' >&${opkg_conf_fd}
+ fclose ${opkg_conf_fd}
+ fclose ${pkgs_fd}
+
+ pkgs="$(resolve_deps "$(cat "${chroot}/.prokit/packages")" \
+ "${install_deps}" | xargs printf '%s\n' | sort -u)"
+ printf '%s\n' "${pkgs}" >"${chroot}/.prokit/packages"
+}
+
+install_deps_cb()
+{
+ local pkg="${1}"
+ local deps="${2}"
+
+ install_deps="${install_deps}${pkg}: ${deps}${LF}"
+}
+
+install_fname_cb()
+{
+ local pkg="${1}"
+ local fname="${2}"
+
+ install_fnames="$(printf '%s\n%s %s/%s' "${install_fnames}" \
+ "${pkg}" "${install_feed_url}" "${fname}")"
+}
+
+install_md5sum_cb()
+{
+ local pkg="${1}"
+ local md5sum="${2}"
+
+ install_md5sums="$(printf '%s\n%s %s' "${install_md5sums}" \
+ "${pkg}" "${md5sum}")"
+}
+
+install_sha256sum_cb()
+{
+ local pkg="${1}"
+ local sha256sum="${2}"
+
+ install_sha256sums="$(printf '%s\n%s %s' \
+ "${install_sha256sums}" "${pkg}" "${sha256sum}")"
+}
+
+install_get_pkgs()
+{
+ local chroot="${1}"
+ local status_fd=
+ local pkg=
+ local fname=
+ local md5sum=
+ local sha256sum=
+ local file=
+ local control=
+ local field=
+ local printed=
+
+ mkdir -p "${chroot}/var/cache/opkg/archives" "${chroot}/tmp/opkg" \
+ "${chroot}/var/lib/opkg/info"
+
+ fopen "${chroot}/var/lib/opkg/status" 'w'
+ status_fd=${FD}
+
+ for pkg in $(cat "${chroot}/.prokit/packages"); do
+ info "$(get_msg 'install_downloading_pkg')" "${pkg}"
+ fname="$(printf '%s\n' "${install_fnames}" | \
+ sed -n "s/^${pkg} //p")"
+ md5sum="$(printf '%s\n' "${install_md5sums}" | \
+ sed -n "s/^${pkg} //p")"
+ sha256sum="$(printf '%s\n' "${install_sha256sums}" | \
+ sed -n "s/^${pkg} //p")"
+ wget -q -O "${chroot}/var/cache/opkg/archives/${fname##*/}" \
+ "${fname}" || \
+ error 2 "$(get_msg 'install_downloading_pkg_fail')"
+ fname="var/cache/opkg/archives/${fname##*/}"
+ if [ "x${md5sum}" != 'x' ]; then
+ printf '%s %s\n' \
+ "${md5sum}" "${chroot}/${fname}" | \
+ md5sum -c >/dev/null 2>&1 || \
+ error 2 "$(get_msg 'install_checksum_fail')"
+ fi
+ if [ "x${sha256sum}" != 'x' ]; then
+ printf '%s %s\n' \
+ "${sha256sum}" "${chroot}/${fname}" | \
+ sha256sum -c >/dev/null 2>&1 || \
+ error 2 "$(get_msg 'install_checksum_fail')"
+ fi
+
+ info "$(get_msg 'install_unpacking_pkg')" "${pkg}"
+ mkdir "${chroot}/tmp/opkg/${pkg}"
+ (
+ cd "${chroot}"
+ tar -xzOf "${fname}" data.tar.gz \
+ >"tmp/opkg/${pkg}/data.tar.gz"
+ tar -xzf "tmp/opkg/${pkg}/data.tar.gz"
+ cd "tmp/opkg/${pkg}"
+ tar -xzOf "../../../${fname}" control.tar.gz | \
+ tar -xz
+ )
+ tar -tzf "${chroot}/tmp/opkg/${pkg}/data.tar.gz" | \
+ sed 's/^\.//' >"${chroot}/var/lib/opkg/info/${pkg}.list"
+ rm -f "${chroot}/tmp/opkg/${pkg}/data.tar.gz"
+ for file in "${chroot}/tmp/opkg/${pkg}/"*; do
+ mv "${file}" \
+ "${chroot}/var/lib/opkg/info/${pkg}.${file##*/}"
+ done
+ rmdir "${chroot}/tmp/opkg/${pkg}"
+
+ # Write status file.
+ control="${chroot}/var/lib/opkg/info/${pkg}.control"
+ for field in Package Version Depends Recommends Suggests \
+ Provides Replaces Conflicts; do
+ grep "^${field}: " "${control}" >&${status_fd}
+ done
+ printf 'Status: install ok unpacked\n' >&${status_fd}
+ for field in Essential Architecture; do
+ grep "^${field}: " "${control}" >&${status_fd}
+ done
+ if [ -r "${chroot}/var/lib/opkg/info/${pkg}.conffiles" ]; then
+ printed=false
+ while read -r file; do
+ ${printed} || printf 'Conffiles:\n' \
+ >&${status_fd}
+ printf ' %s %s\n' "${file}" "$(md5sum \
+ "${chroot}/${file}" | cut -d' ' -f1)" \
+ >&${status_fd}
+ printed=true
+ done <"${chroot}/var/lib/opkg/info/${pkg}.conffiles"
+ fi
+ printf 'Installed-Time: %s\n\n' "$(date '+%s')" >&${status_fd}
+
+ rm -f "${chroot}/${fname}"
+ done
+
+ rm "${chroot}/.prokit/packages"
+ rmdir "${chroot}/.prokit"
+
+ fclose ${status_fd}
+}