#!/bin/sh # Author : Benoit PAPILLAULT # Creation : 2004-11-25 # Design document: # http://benoit.papillault.free.fr/sourcemage/cast-binary.php # usage: get_sorcery_host get_sorcery_host() { local config="${INSTALL_ROOT}/etc/sorcery/config" if [ -f "${config}" ]; then # we start a subshell to avoid polluting our variables # warning : if INSTALL_ROOT is not / and since "config" will try to # source other files, we might get into problems. ( . "${config}"; echo "${HOST}") fi } # usage: get_spell_version $spell get_spell_version() { local spell="$1" # check if we have a "packages" file, otherwise, we return a empty string if [ -f "${INSTALL_ROOT}/var/state/sorcery/packages" ]; then grep "^${spell}:" "${INSTALL_ROOT}/var/state/sorcery/packages"| cut -d: -f4|head -n 1 fi } # usage: copy_local_depends $SPELL # copy $INSTALL_ROOT/etc/sorcey/local/depends/$SPELL{.p} if any # to the current directory copy_local_depends() { local SPELL="$1" # copy /etc/sorcery/local/depends files local DEPENDS_DIR=/etc/sorcery/local/depends local DEPENDS="${DEPENDS_DIR}/${SPELL}" if [ -f "${INSTALL_ROOT}/${DEPENDS}" ]; then mkdir -p "./${DEPENDS_DIR}" && cp -a "${INSTALL_ROOT}/${DEPENDS}" "./${DEPENDS_DIR}" fi local DEPENDS="${DEPENDS_DIR}/${SPELL}.p" if [ -f "${INSTALL_ROOT}/${DEPENDS}" ]; then mkdir -p "./${DEPENDS_DIR}" && cp -a "${INSTALL_ROOT}/${DEPENDS}" "./${DEPENDS_DIR}" fi } # usage: get_depends $spell # output one line for each dependency. each dependency is a spell name get_depends() { local spell="$1" # check if we have a "depends" file # warning, some spells depends on generic provider and the spell name field # is for instance : util-linux(UTIL-LINUX) # we remove the () part. local depends="${INSTALL_ROOT}/var/state/sorcery/depends" if [ -f "${depends}" ]; then grep "^${spell}:" "${depends}" true fi } # usage: get_spell_dir $spell # returns the directory containing spell files # something like /var/lib/sorcery/codex/stable/libs/glibc for the glibc spell get_spell_dir() { local spell="$1" find "${INSTALL_ROOT}/var/lib/sorcery/codex" -mindepth 3 -maxdepth 3 \ -type d -name "${spell}" | head -n 1 } # usage: get_build_api $spell_dir # this returns the BUILD_API specified in the first spell found in # /var/lib/sorcery/codex get_build_api() { local spell_dir="$1" if [ -z "${spell_dir}" ]; then echo "cannot find spell ${spell} in grimoires" exit 1 fi local build_api # spell level local spell_config="${spell_dir}/DETAILS" if [ -f "${spell_config}" ]; then build_api=`. "${spell_config}"; echo "${BUILD_API}"` fi # section level (if not defined at the spell level) if [ -z "${build_api}" ]; then local section_config="${spell_dir}/../API_VERSION" if [ -f "${section_config}" ]; then build_api=`. "${section_config}"; echo "${BUILD_API}"` fi fi # grimoire level (if not already defined) if [ -z "${build_api}" ]; then local grimoire_config="${spell_dir}/../../API_VERSION" if [ -f "${grimoire_config}" ]; then build_api=`. "${grimoire_config}"; echo "${BUILD_API}"` fi fi # default value if not already defined if [ -z "${build_api}" ]; then build_api=1 fi echo "${build_api}" } # usage: get_postinst $spell # output the postinst file from either POST_INSTALL (BUILD_API=1) # or FINAL (BUILD_API=2) get_postinst() { local spell="$1" local spell_dir=`get_spell_dir "${spell}"` local build_api=`get_build_api "${spell_dir}"` case "${build_api}" in 1) if [ -f "${spell_dir}/POST_INSTALL" ]; then cat "${spell_dir}/POST_INSTALL" fi ;; 2) if [ -f "${spell_dir}/FINAL" ]; then cat "${spell_dir}/FINAL" fi ;; esac } # usage: package_depends spell # stdin is read for dependencies information # lines have the same format as /var/state/sorcery/depends # call spell-binary-make for all dependencies package_depends() { local SPELL="$1" grep "^${SPELL}:.*:on:.*" | cut -d: -f2 | cut -d'(' -f1| while read dep_spell; do spell-binary-make "${dep_spell}" done } # usage: make_binary_cache spell version # the resulting cache file name is written on stdout make_binary_cache() { local SPELL="$1" local VERSION="$2" local INSTALL="${INSTALL_ROOT}/var/log/sorcery/install/${SPELL}-${VERSION}" if [ ! -f "${INSTALL}" ]; then exit 1 fi # remove all leading / rm -rf "/tmp/ls.${SPELL}" && sed 's:^\(/*\)::' "${INSTALL}" > "/tmp/ls.${SPELL}" local CACHE="/tmp/${SPELL}-${VERSION}-iso.tar.bz2" (cd "${INSTALL_ROOT}" && tar jcf "${CACHE}" --no-recursion -T "/tmp/ls.${SPELL}" && echo "${CACHE}" ) rm "/tmp/ls.${SPELL}" } main() { if [ $# -ne 1 ]; then echo "usage: $0 spell" exit 1 fi local SPELL="$1" # default values if [ -z "${BASE}" ]; then BASE=. fi if [ -z "${INSTALL_ROOT}" ]; then INSTALL_ROOT=/ fi local VERSION=`get_spell_version "${SPELL}"` if [ -z "${VERSION}" ]; then echo "${SPELL} is not installed in ${INSTALL_ROOT}" exit 1 fi echo "spell ${SPELL} version ${VERSION} is being investigated" local HOST=`get_sorcery_host` if [ -z "${HOST}" ]; then echo "sorcery architecture is unknown, check your sorcery settings" exit 1 fi # compute canonic name (replace _ by -) local C_SPELL=`echo "${SPELL}" | sed s/_/-/g` local C_VERSION=`echo "${VERSION}" | sed s/_/-/g` local C_HOST=`echo "${HOST}" | sed s/_/-/g` local PKG="${C_SPELL}_${C_VERSION}_${C_HOST}.tar.bz2" # check if the package already exist (it may already exist since we # are checking dependencies recursively) if [ -f "${BASE}/${PKG}" ]; then echo "spell ${SPELL} version ${VERSION} is already packaged" exit 0 fi # look for the precompiled binary cache CACHE="${INSTALL_ROOT}/var/cache/sorcery/${SPELL}-${VERSION}-${HOST}.tar.bz2" if [ ! -f "${CACHE}" ]; then # we need to make a cache ourselves (TO BE IMPLEMENTED) CACHE=`make_binary_cache "${SPELL}" "${VERSION}"` if [ -z "${CACHE}" ]; then echo "no binary cache found and cannot make one" exit 1 fi fi # package dependencies first get_depends "${SPELL}" | package_depends "${SPELL}" # create a temporary directory local tmpdir="/tmp/spell-binary-$$" rm -rf "${tmpdir}" && mkdir -p "${tmpdir}" && ( cd "${tmpdir}" && tar jxf "${CACHE}" && mkdir -p install && copy_local_depends "${SPELL}" && get_depends "${SPELL}" > install/depends && get_postinst "${SPELL}" > install/postinst && if [ -s install/postinst ]; then chmod a+x install/postinst else rm install/postinst fi ) && ( echo "spell ${SPELL} version ${VERSION} is being packaged" && mkdir -p "${BASE}" && tar jcf "${BASE}/${PKG}" -C "${tmpdir}" . ) && echo "spell ${SPELL} version ${VERSION} is packaged" rm -rf "${tmpdir}" } main "$@"