#! /bin/sh # # slxossetup - OpenSLX script for OS setup # # (c) 2006 - OpenSLX.com # # Lars Müller # : ${SLX_CONFIG_PATH:=/etc/opt/openslx} : ${SLX_PRIVATE_PATH:=/var/opt/openslx} : ${SLX_BOOTSTRAP_PATH:="/slxbootstrap"} : ${SLX_STAGE1_FINAL_PATH:="/slxfinal"} SLX_SYSTEM_BASENAME=$1 test "$2" && \ SLX_OSSETUP_MODE=$2 || SLX_OSSETUP_MODE="bootstrap" PATH="/sbin:/bin:/usr/bin:/usr/sbin" function ErrorMsg() { echo "$0: $2" exit $1 } test -z "${SLX_SYSTEM_BASENAME}" && \ ErrorMsg 1 "Error, not provided! " for dir in . ${SLX_CONFIG_PATH}; do if test -d "${dir}/systems/${SLX_SYSTEM_BASENAME}"; then SLX_SYSTEM_CONFIG_PATH="${dir}/systems/${SLX_SYSTEM_BASENAME}" break fi done test -z "${SLX_SYSTEM_CONFIG_PATH}" && \ ErrorMsg 1 "Error, system named ${SLX_SYSTEM_BASENAME} not found in systems sub directory of . nor ${SLX_CONFIG_PATH} " for dir in ${SLX_CONFIG_PATH} .; do for file in settings.default settings.local; do file="${dir}/${file}" test -f "${file}" && \ . "${file}" done done SLX_BUSYBOX_CHROOT_NAME="busybox_chroot" # Read config files for a particular system for suffix in "" local; do test -f "${SLX_SYSTEM_CONFIG_PATH}/settings${suffix:+.$suffix}" && \ . "${SLX_SYSTEM_CONFIG_PATH}/settings${suffix:+.$suffix}" done function setup_busybox_init() { test -d "${SLX_STAGE1_PATH}" && \ ErrorMsg 1 "Error, ${SLX_STAGE1_PATH} already exists! " } function setup_busybox_chroot() { local dir file PERL_PATH BUSYBOX_PATH BUSYBOX_LINKS_PATH REQUIRED_LIBS BUSYBOX_PATH="${SLX_SHARE_PATH}/busybox/busybox" BUSYBOX_LINKS_PATH="${SLX_SHARE_PATH}/busybox/busybox.links" case "${REPO_TYPE}" in *deb*) PERL_PATH=$( type -p perl) test -z "${PERL_PATH}" && \ ErrorMsg 1 "Error, perl is not in your path, $PATH. " test -d "${CHROOT_DIR}/usr/bin/" || \ mkdir -p "${CHROOT_DIR}/usr/bin/" cp -p "${PERL_PATH}" "${CHROOT_DIR}/usr/bin/" ;; esac test -d "${CHROOT_DIR}/bin" || \ mkdir -p "${CHROOT_DIR}/bin" cp -p "${BUSYBOX_PATH}" "${CHROOT_DIR}/bin/" REQUIRED_LIBS=$( for file in ${CHROOT_DIR}/bin/* ${CHROOT_DIR}/usr/bin/*; do test -e $file || \ continue ${SLX_BIN_PATH}/slxldd $file; done) for file in ${REQUIRED_LIBS}; do test -e "${CHROOT_DIR}/${file}" && \ continue dir="${CHROOT_DIR}/${file%/*}" test -d "${dir}" || \ mkdir -p "${dir}" cp -p "${file}" "${dir}/" done while read file; do dir="${CHROOT_DIR}/${file%/*}" test -d "${dir}" || \ mkdir -p "${dir}" ln -s "/bin/busybox" "${CHROOT_DIR}/${file}" done <"${BUSYBOX_LINKS_PATH}" test -d "${CHROOT_DIR}/etc" || \ mkdir -p "${CHROOT_DIR}/etc" cp -p /etc/resolv.conf "${CHROOT_DIR}/etc/" # FIXME this might not be enough to satisfy the resolver for file in /lib/libnss_dns* /lib/libresolv*; do test -e "${file}" || \ continue dir="${CHROOT_DIR}/${file%/*}" test -d "${dir}" || \ mkdir -p "${dir}" cp -p "${file}" "${dir}/" done } function setup_busybox_stage1_config() { local key value CONFIG_FILE CONFIG_FILE="${CHROOT_DIR}/etc/slxbootstrap.conf" test -d "${CHROOT_DIR}/etc" || \ mkdir -p "${CHROOT_DIR}/etc" echo "# OpenSLX bootstrap configuration file" >"${CONFIG_FILE}" for key in \ SLX_BASE_BOOTSTRAP_PACKAGES \ SLX_BASE_BOOTSTRAP_PREREQ_PACKAGES \ SLX_BASE_PREREQ_PACKAGES \ SLX_BOOTSTRAP_FAIL_WGET \ SLX_STAGE1_FINAL_PATH \ SLX_INST_ARCH \ SLX_INST_SOURCE_BASEURL \ SLX_INST_SOURCE_DISTRIBUTION \ SLX_INST_SOURCE_PACKAGEKEYS \ SLX_INST_SOURCE_PACKAGE_SUBDIR \ ; do value=$( eval echo \$$key) test "${value}" || \ continue echo $key=\"$value\" >>"${CONFIG_FILE}" done test -d "${CHROOT_DIR}/bin" || \ mkdir -p "${CHROOT_DIR}/bin" cp -p "${SLX_SHARE_PATH}"/busybox/slx* "${CHROOT_DIR}/bin" } function setup_busybox_install_prereq_file() { if test -d "${SLX_SYSTEM_CONFIG_PATH}/prereqfiles"; then test -d "${CHROOT_DIR}/etc/prereqfiles/" || \ mkdir -p "${CHROOT_DIR}/etc/prereqfiles/" cp -pr "${SLX_SYSTEM_CONFIG_PATH}"/prereqfiles/* "${CHROOT_DIR}/etc/prereqfiles/" find "${SLX_STAGE1_PATH}" -type d -name .svn -print0 | \ xargs -0 rm -rf fi if test -x "${SLX_SYSTEM_CONFIG_PATH}/scripts/postprereq"; then test -d "${CHROOT_DIR}/bin" || mkdir -p "${CHROOT_DIR}/bin" cp -p "${SLX_SYSTEM_CONFIG_PATH}"/scripts/postprereq "${CHROOT_DIR}/bin/" fi } function setup_bootstrap_1b() { chroot "${CHROOT_DIR}" /bin/slxbootstrap test $? != 0 && \ ErrorMsg 1 "Error while calling /bin/slxbootstrap inside chroot, ${CHROOT_DIR}. " } function create_package_list() { local file packagelist packagelist=$@ for file in ${packagelist}; do test "${SLX_BOOTSTRAP_FAIL_WGET}" = "no" -a \ ! -f ${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/${file##*/} && \ continue echo -n "${file##*/} " done } function setup_bootstrap_1c() { local dir file packagelist packagekey rc case "${SLX_SYSTEM_BASENAME}" in *debian*|*ubuntu*) test -d "${SLX_STAGE1_FINAL_PATH}" || \ mkdir -p "${SLX_STAGE1_FINAL_PATH}" DEBOOTSTRAP_DIR="${SLX_BOOTSTRAP_PATH}/usr/lib/debootstrap" \ chroot "${CHROOT_DIR}" /bin/ash \ "${SLX_BOOTSTRAP_PATH}/usr/sbin/debootstrap" \ ${SLX_INST_ARCH:+--arch $SLX_INST_ARCH} \ "${SLX_INST_SOURCE_DISTRIBUTION}" \ "${SLX_BOOTSTRAP_PATH}/${SLX_STAGE1_FINAL_PATH}" \ "${SLX_INST_SOURCE_BASEURL}" rc=$? test ${rc} -eq 0 || \ ErrorMsg ${rc} "Bootstrap failed! " ;; *suse*|*fedora*|*mandriva*) test -d "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/etc" || \ mkdir "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/etc" touch "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/etc/mtab" for file in ${SLX_INSTALL_FAKE_FILE}; do dir="${file%/*}" test -d "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/${SLX_STAGE1_FINAL_PATH}/${dir}" || \ mkdir -p "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/${SLX_STAGE1_FINAL_PATH}/${dir}" touch "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/${SLX_STAGE1_FINAL_PATH}/${file}" done for packagekey in ${SLX_INST_SOURCE_PACKAGEKEYS}; do chroot "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}" \ /bin/rpm --root="${SLX_STAGE1_FINAL_PATH}" --import "${packagekey}" done packagelist=$( create_package_list ${SLX_BASE_BOOTSTRAP_PREREQ_PACKAGES}) if test "${packagelist}"; then chroot "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}" \ /bin/rpm --root="${SLX_STAGE1_FINAL_PATH}" \ -ivh --nodeps --noscripts --force \ ${packagelist} # Remove RPM DB; else the following call to rpm fails. rm -rf "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/${SLX_STAGE1_FINAL_PATH}/var/lib/rpm" fi packagelist=$( create_package_list ${SLX_BASE_PREREQ_PACKAGES} ${SLX_BASE_BOOTSTRAP_PACKAGES} ${SLX_BASE_BOOTSTRAP_PREREQ_PACKAGES}) test -z "{packagelist}" && \ ErrorMsg 1 "Packagelist to bootstrap from ${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH} is empty." chroot "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}" \ /bin/rpm --root="${SLX_STAGE1_FINAL_PATH}" -ivh ${packagelist} rc=$? test ${rc} -eq 0 || \ ErrorMsg ${rc} "Bootstrap failed! " cp -p /etc/resolv.conf "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/${SLX_STAGE1_FINAL_PATH}/etc/" ;; esac mv "${CHROOT_DIR}/${SLX_BOOTSTRAP_PATH}/${SLX_STAGE1_FINAL_PATH}/"* "${SLX_STAGE1_PATH}/" rm -rf ${CHROOT_DIR} } function setup_package_sources() { local SOURCES_LIST URPMI_ADDMEDIA_ARG case "${SLX_SYSTEM_BASENAME}" in *debian*|*ubuntu*) SOURCES_LIST="${SLX_STAGE1_PATH}/etc/apt/sources.list" rm -f "${SOURCES_LIST}" ;; *fedora*) rm -f "${SLX_STAGE1_PATH}/etc/yum.repos.d/"* ;; esac # Add available installation sources to an installed system. # For systems using apt we're able to do this from outside. for variable in ${!SLX_INST_SOURCE_NAME_*}; do # Unset INST_SOURCE_* to let the meta packager fail if they are not set for a particular # channel; unset PACKAGEKEYS to prevent adding them multiple times. unset INST_SOURCE_COMPONENTS \ INST_SOURCE_DISTRIBUTION \ INST_SOURCE_NAME \ INST_SOURCE_PRIORITY \ INST_SOURCE_REPO_SUBDIR \ INST_SOURCE_TYPE \ PACKAGEKEYS INST_SOURCE_CHANNEL="${variable##*_}" INST_SOURCE_BASEURL=$( eval echo \$SLX_INST_SOURCE_BASEURL_${INST_SOURCE_CHANNEL}) INST_SOURCE_NAME=$( eval echo \$$variable) test "${INST_SOURCE_NAME}" || \ INST_SOURCE_NAME="${INST_SOURCE_CHANNEL}" INST_SOURCE_PACKAGE_SUBDIR=$( eval echo \$SLX_INST_SOURCE_PACKAGE_SUBDIR${INST_SOURCE_CHANNEL}) INST_SOURCE_REPO_SUBDIR=$( eval echo \$SLX_INST_SOURCE_REPO_SUBDIR_${INST_SOURCE_CHANNEL}) INST_SOURCE_TYPE=$( eval echo \$SLX_INST_SOURCE_TYPE_${INST_SOURCE_CHANNEL}) # Use default repo type if not available from settings config file test "${INST_SOURCE_TYPE}" || \ INST_SOURCE_TYPE="${REPO_TYPE}" # Has this config distribution, components INST_SOURCE_DISTRIBUTION=$( eval echo \$SLX_INST_SOURCE_DISTRIBUTION_${INST_SOURCE_CHANNEL}) INST_SOURCE_COMPONENTS=$( eval echo \$SLX_INST_SOURCE_COMPONENTS_${INST_SOURCE_CHANNEL}) INST_SOURCE_PRIORITY=$( eval echo \$SLX_INST_SOURCE_PRIORITY_${INST_SOURCE_CHANNEL}) # Check if one of our global settings is still undefined for setting in ${GLOBAL_SETTINGS}; do test "$( eval echo \$INST_SOURCE_${setting})" || \ eval INST_SOURCE_${setting}=\$SLX_INST_SOURCE_${setting} done echo "$0: Adding installation source name=\"${INST_SOURCE_NAME}\", baseurl=\"${INST_SOURCE_BASEURL}${INST_SOURCE_REPO_SUBDIR:+/${INST_SOURCE_REPO_SUBDIR}}\". " case "${META_PACKAGER}" in apt-get) echo "deb ${INST_SOURCE_BASEURL} ${INST_SOURCE_DISTRIBUTION} ${INST_SOURCE_COMPONENTS}" \ >>${SOURCES_LIST} # FIXME Add feature to sort the lines by given (?) priority. ;; smart) # Prefix the config name for optional parameters test "${INST_SOURCE_PRIORITY}" && \ INST_SOURCE_PRIORITY="priority=\"${INST_SOURCE_PRIORITY}\"" eval LC_ALL=POSIX chroot ${SLX_STAGE1_PATH} smart \ channel \ --add \"${INST_SOURCE_CHANNEL}\" \ name=\"${INST_SOURCE_NAME}\" \ type=\"${INST_SOURCE_TYPE}\" \ baseurl=\"${INST_SOURCE_BASEURL}\" \ ${INST_SOURCE_PRIORITY} \ -y ;; urpmi) case "${INST_SOURCE_PACKAGE_SUBDIR}" in */updates) URPMI_ADDMEDIA_ARG="--update" ;; *) URPMI_ADDMEDIA_ARG="" ;; esac eval LC_ALL=POSIX chroot ${SLX_STAGE1_PATH} urpmi.addmedia \ ${URPMI_ADDMEDIA_ARG} \ \"${INST_SOURCE_CHANNEL}\" \ \"${INST_SOURCE_BASEURL}/${INST_SOURCE_PACKAGE_SUBDIR}\" \ with media_info/hdlist.cz ;; yum) echo -e "[${INST_SOURCE_CHANNEL}]\nname=${INST_SOURCE_NAME}\nbaseurl=${INST_SOURCE_BASEURL}${INST_SOURCE_REPO_SUBDIR:+/${INST_SOURCE_REPO_SUBDIR}}" \ >${SLX_STAGE1_PATH}/etc/yum.repos.d/${INST_SOURCE_CHANNEL}.repo ;; esac done } # Install all available updates for an installed system. # Before we have to ensure to have the install sources up to date. function update_system() { test -z "${SLX_STAGE1_PATH}" && \ ErrorMsg 1 "Error: SLX_STAGE1_PATH is not set. " case "${META_PACKAGER}" in apt-get) : ${SLX_STAGE1_UPDATE_OPTIONS:=-y} : ${SLX_STAGE1_UPGRADE_OPTIONS:=-y} chroot "${SLX_STAGE1_PATH}" apt-get update ${SLX_STAGE1_UPDATE_OPTIONS} chroot "${SLX_STAGE1_PATH}" apt-get upgrade ${SLX_STAGE1_UPGRADE_OPTIONS} ;; smart) : ${SLX_STAGE1_UPGRADE_OPTIONS:=-y} LC_ALL=POSIX chroot "${SLX_STAGE1_PATH}" smart upgrade --update ${SLX_STAGE1_UPGRADE_OPTIONS} ;; yum) : ${SLX_STAGE1_UPDATE_OPTIONS:=-y} cp -p /proc/cpuinfo "${SLX_STAGE1_PATH}/proc/cpuinfo" LC_ALL=POSIX chroot "${SLX_STAGE1_PATH}" yum ${SLX_STAGE1_UPDATE_OPTIONS} update rm "${SLX_STAGE1_PATH}/proc/cpuinfo" ;; esac } function install_slxselection() { test -z "${SLX_STAGE1_PATH}" && \ ErrorMsg 1 "Error: SLX_STAGE1_PATH is not set. " local packages packagelist variable for variable in ${!SLX_INSTALL_PACKAGES_*}; do packages=$( eval echo \$$variable) packagelist="${packagelist:+$packagelist }$( eval echo \$$variable)" done test -z "${packagelist}" && \ return case "${META_PACKAGER}" in apt-get) : ${SLX_STAGE1_INSTALL_OPTIONS:=-y} chroot "${SLX_STAGE1_PATH}" apt-get install ${SLX_STAGE1_INSTALL_OPTIONS} ${packagelist} ;; smart) : ${SLX_STAGE1_INSTALL_OPTIONS:=-y} LC_ALL=POSIX chroot "${SLX_STAGE1_PATH}" smart install ${SLX_STAGE1_INSTALL_OPTIONS} ${packagelist} ;; yum) : ${SLX_STAGE1_INSTALL_OPTIONS:=-y} cp -p /proc/cpuinfo "${SLX_STAGE1_PATH}/proc/cpuinfo" LC_ALL=POSIX chroot "${SLX_STAGE1_PATH}" yum ${SLX_STAGE1_INSTALL_OPTIONS} install ${packagelist} rm "${SLX_STAGE1_PATH}/proc/cpuinfo" ;; esac } function slxossetup_busybox() { local CHROOT_DIR setup_busybox_init test -z "${SLX_STAGE1_PATH}" -o -z "${SLX_BUSYBOX_CHROOT_NAME}" && \ ErrorMsg 1 "Error: SLX_STAGE1_PATH or SLX_BUSYBOX_CHROOT_NAME is not set. " CHROOT_DIR="${SLX_STAGE1_PATH}/${SLX_BUSYBOX_CHROOT_NAME}" setup_busybox_chroot setup_busybox_stage1_config setup_busybox_install_prereq_file setup_bootstrap_1b setup_bootstrap_1c setup_package_sources update_system install_slxselection } function slxossetup_init() { SLX_STAGE1_PATH="${SLX_PRIVATE_PATH}/stage1/${SLX_SYSTEM_BASENAME}" } function slxossetup() { slxossetup_init case "${SLX_SYSTEM_BASENAME}" in *suse*) # Inform SUSE RPMs that we're performing an installation # This is only important in stage 1c export YAST_IS_RUNNING="instsys" GLOBAL_SETTINGS="BASEURL PACKAGEKEYS" test "${SLX_META_PACKAGER}" && \ META_PACKAGER="${SLX_META_PACKAGER}" || \ META_PACKAGER="yum" REPO_TYPE="rpm-md" ;; *fedora*) GLOBAL_SETTINGS="BASEURL PACKAGEKEYS" test "${SLX_META_PACKAGER}" && \ META_PACKAGER="${SLX_META_PACKAGER}" || \ META_PACKAGER="yum" REPO_TYPE="rpm-md" ;; *mandriva*) GLOBAL_SETTINGS="BASEURL PACKAGE_SUBDIR" test "${SLX_META_PACKAGER}" && \ META_PACKAGER="${SLX_META_PACKAGER}" || \ META_PACKAGER="urpmi" REPO_TYPE="rpm-md" ;; *debian*|*ubuntu*) GLOBAL_SETTINGS="BASEURL COMPONENTS DISTRIBUTION" test "${SLX_META_PACKAGER}" && \ META_PACKAGER="${SLX_META_PACKAGER}" || \ META_PACKAGER="apt-get" REPO_TYPE="apt-deb" X86_ARCH='i386' ;; *) ErrorMsg 1 "Unknown system ${SLX_SYSTEM_BASENAME}. " ;; esac if test -z "${SLX_INST_ARCH}"; then SLX_INST_ARCH=$( uname -m) case "${SLX_INST_ARCH}" in i*86) SLX_INST_ARCH="${X86_ARCH}" ;; x86_64) # Redefine SLX_INST_ARCH in the case of Debian # based systems. Here we might need to differ # between the vendors architecture name and the # named used by the OS kernel. case "${SLX_SYSTEM_BASENAME}" in *debian*|*ubuntu*) SLX_INST_ARCH='amd64' ;; esac ;; *) ErrorMsg 1 "Unsupported machine hardware ${SLX_INST_ARCH}." ;; esac fi case "${SLX_OSSETUP_MODE}" in bootstrap) slxossetup_busybox ;; package-source) setup_package_sources ;; install-selection) install_slxselection ;; esac } case "${SLX_OSSETUP_MODE}" in bootstrap|package-source|install-selection) slxossetup ;; *) echo "Usage: $0 system-name [bootstrap|package-source|install-selection]" ;; esac