From 61c9b1c97b1f5d07183987c2256637e523d1ff17 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 2 Jan 2014 19:36:42 +0100 Subject: !! Split up 'mltk' into 'mltk' and 'openslx' !! 'mltk remote' is now 'mltk' 'mltk server' is now 'openslx' Also changed the export type (-e) stage31 to 'cpio' and stage32 and addons to 'sqfs' It should describe what it's packed as, not what the meaning of the content is; you can already tell from the file name. --- helper/binutil.inc | 214 ----------------------------------------------- helper/distribution.inc | 56 +------------ helper/downloader.inc | 71 ---------------- helper/fileutil.inc | 199 -------------------------------------------- helper/kernel.inc | 178 --------------------------------------- helper/keyvalueutil.inc | 32 ------- helper/string.inc | 8 +- helper/system.inc | 42 ---------- helper/useradd.inc | 215 ------------------------------------------------ 9 files changed, 6 insertions(+), 1009 deletions(-) delete mode 100644 helper/binutil.inc delete mode 100644 helper/downloader.inc delete mode 100644 helper/kernel.inc delete mode 100644 helper/keyvalueutil.inc delete mode 100644 helper/system.inc delete mode 100644 helper/useradd.inc (limited to 'helper') diff --git a/helper/binutil.inc b/helper/binutil.inc deleted file mode 100644 index aa793e08..00000000 --- a/helper/binutil.inc +++ /dev/null @@ -1,214 +0,0 @@ -#!/bin/bash -# -# Common functions to copy binaries and their dependancies. -# -############################################################ -# This will parse the output of ldd on given binaries -# and echo the location of these libs to STDOUT -# The output of this function has to be used in some -# way, it only echos! -# -# About local search: -# It is required that we can search for the dynamic -# libraries in a specific directory, namely the one -# where we (potentially) built the binary. If a -# corresponding library is found, it should take -# precedence over ones found on the system. -# This can be done by using the '-l' switch, see below. -# -############################################################ -# We use a blacklist mechanism to exclude common libraries. -# This improves runtime quite a bit... -BLACKLIST="ld-linux linux-gate linux-vdso libc.so" - -# Initialise flag and path for local search -LOCALSEARCH=0 -LOCALSEARCHDIR="" - -# replace ' ' by '|' in the blacklist, so grep can use it directly. -CURRENT_BLACKLIST=$(echo ${BLACKLIST} | sed 's/ /\\|/g') - -############################################################ -# -# Usage: -# get_dynamic_dependencies [-l ] -# * the list must be seperated by spaces -# * the search for lib needed by a binary can be done locally, -# using the -l option -# -# Ouput: -# Will simply echo list of required libraries - -get_dynamic_dependencies() { - # check if local search is activated by the '-l' switch - # if so the following argument is the path. - if [ "x$1" == "x-l" ]; then - LOCALSEARCH=1 - shift - [ ! -d "$1" ] && perror "Directory '$1' does not exist, exiting." - LOCALSEARCHDIR="$1" - shift - fi - - # main loop over the list of binaries - while [ $# != 0 ]; do - local BINARY="$1" - shift - - # now run ldd on it and save the output in $LDD_OUT - local LDD_OUT="ldd_output" - if ldd "$BINARY" > "$LDD_OUT"; then - # Case 1: file is a dynamic executable - for LIB in $(grep -v "${CURRENT_BLACKLIST}${REQUIRED_LDD_BLACKLIST}" "$LDD_OUT" | awk '{print $1 $2 $3}'); do - # split the entry into an array, ex: - # libm.so.6 => /lib/libm.so.6 would be split into: - # LIBLINK[0] LIBLINK[1] - local LIBLINK=(${LIB//=>/ }) - # call helper function to find the correct lib - lib_search - done - #TODO: check if "statically linked" is output - else - # Case 2: not a dynamic, do nothing - pdebug "\t\t\t(Not a dynamic.)" - rm -f "$LDD_OUT" - continue - fi - rm -f "$LDD_OUT" - done - -} - -############################################################ -# -# Usage: -# lib_search -# -# Output: -# List of the path including any possible symbolic links -# of the found libraries. -# -# Note: This function takes no argument. It takes the library -# to look for from the local array LIBLINK. -# If the local was activated in get_dynamic_dependencies -# this will search for the library in LOCALSEARCHDIR first. -# If its not found, then it will look system-wide. -lib_search() { - - # if activated, start by searching the lib locally - if [ "x$LOCALSEARCH" == "x1" ]; then - cd "$LOCALSEARCHDIR" - local LOCAL_MATCHES=$(find . -name "${LIBLINK[0]}") # | awk -F '.' '{print $1}')".so\*) - cd - >/dev/null - if [ "x${LOCAL_MATCHES}" != "x" ]; then - for LOCALLIB in ${LOCAL_MATCHES}; do - get_link_chain "${LOCALSEARCHDIR}/${LOCALLIB}" "${LOCALSEARCHDIR}" - get_dynamic_dependencies -l "${LOCALSEARCHDIR}" "${LOCALLIB}" - CURRENT_BLACKLIST+="\|${LIBLINK[0]}" - done - # found the libs, we are done - return - fi - # mark local search as done - fi - - # search the lib on the system since it was not found earlier - if [ ! -z ${LIBLINK[1]} ] && [ "x${LIBLINK[1]}" != "xnot" ]; then - # get chain of symlink for that lib - get_link_chain "${LIBLINK[1]}" - CURRENT_BLACKLIST+="\|${LIBLINK[1]}" - else - pwarning "\t\tLib '${LIBLINK[0]}' from required dir '$ENTRY' neither found in build directory nor on this system." - pwarning "\t\tIf this lib is not supplied by another module, this module will probably fail in your final system" - fi -} -############################################################ -# -# Usage: -# get_link_chain [prefix] -# * must be in absolute form- -# * [prefix] is the prefix to strip from the ouput. -# -# Output: -# Lists the symlink chain until a hardlink is found. -# -get_link_chain() { - - # sanity checks - if [[ "$1" == /* ]]; then - [ -e $1 ] || perror "get_link_chain: no such file: $1" - else - perror "get_link_chain() requires absolute paths, given: $1" - fi - if [ $# == 2 ] ; then - [ ! -d $2 ] && perror "get_link_chain: $2 is not a directory." - # got a prefix - local PREFIX=$(readlink -f $2) - else - # mark prefix as not set - local PREFIX="notset" - fi - - # canonalize - local LINK=$(canonicalize $1) - - local CHAIN="$LINK" - - # write the first link in the chain - if [ "x$PREFIX" != "x" -a "x$PREFIX" != "xnotset" ]; then - if [ "x${LINK#$PREFIX}" == "x${LINK}" ]; then - # prefix was not in the link - echo "$LINK" - else - # prefix was in the link - echo ./"${LINK#$PREFIX}" - fi - else - # no prefix, copy like it is - echo "$LINK" - fi - - # now we check for symlinks - local TRY=0 - while [ -L "$LINK" ] && [ $TRY -lt 10 ]; do - let TRY=TRY+1 - - # save the directory prefix - CURRENTDIR=$(dirname "${LINK}") - # first follow the link - LINK=$(readlink "$LINK") - CHAIN+=" -> $LINK" - # $LINK can be absolute or relative, check cases - [[ "$LINK" == /* ]] || LINK=$(canonicalize "$CURRENTDIR"/"${LINK}") - # write the first link in the chain - if [ "x$PREFIX" != "x" -a "x$PREFIX" != "xnotset" ]; then - if [ "x${LINK#$PREFIX}" == "x${LINK}" ]; then - # prefix was not in the link - echo "$LINK" - else - # prefix was in the link - echo ./"${LINK#$PREFIX}" - fi - else - # no prefix, copy like it is - echo "$LINK" - fi - done - pdebug "\t\t$CHAIN" -} -############################################################ -# -# Usage: -# list_basic_libs -# -# Output: -# list the path of following basic system libraries: -# - libc.so, ld-linux.so -# -list_basic_libs() { - for i in $(ldd ${SHELL}) - do - [ $(echo $i | grep '^/' | grep -c ld) -eq 1 -o $(echo $i | grep '^/' | grep -c libc.so) -eq 1 ] && get_link_chain $i - done -} - diff --git a/helper/distribution.inc b/helper/distribution.inc index 817baa53..51a01eae 100644 --- a/helper/distribution.inc +++ b/helper/distribution.inc @@ -1,54 +1,2 @@ - - -detect_distribution () { - # Set up distribution and package management - # Lowercase distributor ID is what we use as the general distribution name - SYS_DISTRIBUTION=$(lsb_release -is | tolower | sed -r 's/[^a-z0-9]//g;s/project$//g;s/scientificsl$/scientific/g') - # Then determine packet manager - case "$SYS_DISTRIBUTION" in - ubuntu) - PACKET_MANAGER="apt" - PACKET_HANDLER="dpkg" - detect_ubuntu_lts - ;; - debian) - PACKET_MANAGER="apt" - PACKET_HANDLER="dpkg" - ;; - opensuse) - PACKET_MANAGER="zypper" - PACKET_HANDLER="rpm" - ;; - scientific) - PACKET_MANAGER="yum" - PACKET_HANDLER="rpm" - ;; - *) - perror "Unknown Distribution: $SYS_DISTRIBUTION - Please specify its packet manager in remote/setup_target" - ;; - esac - # Get version - we mangle this quite a bit. first make sure it has no spaces, then split version at period (.), underscore (_) and dash (-) - SYS_VERSION=$(lsb_release -rs | tolower) - local VERSION=$(echo $SYS_VERSION | sed -r 's/\s//g;s/[\._]/ /g;s/-//g') - local STRTMP="" - PRINT_SYS_VERSIONS="*.conf.$SYS_DISTRIBUTION" - SYS_VERSIONS="$SYS_DISTRIBUTION" - for PART in $VERSION; do - [ -z "$PART" ] && continue - STRTMP+=".$PART" - SYS_VERSIONS="${SYS_DISTRIBUTION}${STRTMP} $SYS_VERSIONS" - PRINT_SYS_VERSIONS="*.conf.${SYS_DISTRIBUTION}${STRTMP} $PRINT_SYS_VERSIONS" - done - pinfo "Config source order: *.conf first, then the first one of these (if found)" - pinfo "$PRINT_SYS_VERSIONS" -} - -detect_ubuntu_lts () { - local TMP=$(dpkg -S /usr/bin/Xorg) - [[ "$TMP" == xserver-xorg* ]] || perror "Could not detect xserver package version (returned: $TMP)" - TMP=${TMP%: *} - TMP=${TMP#xserver-xorg-core} - pinfo "Ubuntu LTS Xorg suffix: $TMP" - UBUNTU_XORG_PKG_SUFFIX="$TMP" -} - +# Get simple distribution name +SYS_DISTRIBUTION=$(lsb_release -is | tr '[A-Z]' '[a-z]' | sed -r 's/[^a-z0-9]//g;s/project$//g;s/scientificsl$/scientific/g') diff --git a/helper/downloader.inc b/helper/downloader.inc deleted file mode 100644 index e12c8a02..00000000 --- a/helper/downloader.inc +++ /dev/null @@ -1,71 +0,0 @@ -# helper functions for downloading files or packages - -# download a file. usage: -# download FROM [TO] -# 1. download "http://example.com/something.tar.gz" -# 2. download "http://example.com/something.tar.gz" "somename.tar.gz" -download () { - [ $# -lt 1 -o $# -gt 2 ] && perror "download called with $# arguments, need 1 or 2" - [ -z "$1" ] && perror "download: URL empty." - if [ $# -eq 2 ]; then - [ -z "$2" ] && perror "download: target file name given but empty" - pinfo "Downloading $2 from '$1'...." - wget -O "$2" "$1" - local RET=$? - else - pinfo "Downloading '$1'...." - wget "$1" - local RET=$? - fi - [ "x$RET" != "x0" ] && perror "downloading $1 failed, wget returned exit code $RET" -} - -# download a file and untar it. usage: -# download_untar FROM TO_DIR [TEMPFILE] -# 1. download_untar "http://example.com/something.tar.gz" "src/" -# 2. download_untar "http://example.com/something.tar.gz" "src/" "temporary_name.tar.gz" -download_untar () { - [ $# -lt 2 -o $# -gt 3 ] && perror "download_untar called with $# arguments, need 2 or 3" - local URL="$1" - local DEST="$2" - if [ $# -eq 2 ]; then - local TMPFILE=dltmp.$(basename "$URL") - else - local TMPFILE="$3" - fi - pdebug "$URL ---> $TMPFILE" - download "$URL" "$TMPFILE" - mkdir -p "$DEST" - pinfo "Unpacking to '$DEST'..." - tar xf "$TMPFILE" -C "${DEST}/" - local RET=$? - [ "x$RET" != "x0" ] && perror "could not untar $TMPFILE to $DEST (tar returned $RET)" - unlink "$TMPFILE" -} - -# Download first param URL to second param path, -# iff the local file does not exist or is empty. -# Return 1 if remote file does not exist, 0 otherwise -download_if_empty() { - [ $# -ne 2 ] && perror "download_if_empty: want 2 args, got $# ($@)" - local SRC="$1" - local DST="$2" - [ -s "$DST" ] && pdebug "Not downloading $DST: already there." && return 0 - pdebug "Downloading $DST" - [ -e "$DST" ] && unlink "$DST" - local DSTDIR="$(dirname "$DST")" - pdebug "wgetting $SRC" - local TMP=$(mktemp) - wget -O "$TMP" "$SRC" - local RET=$? - if [ "x$RET" = "x0" -a -s "$TMP" ]; then - mkdir -p "$DSTDIR" - mv "$TMP" "$DST" || perror "Could not mv '$TMP' '$DST'" - return 0 - fi - pdebug "WGET failed" - rmdir "$DSTDIR" - unlink "$TMP" - return 1 -} - diff --git a/helper/fileutil.inc b/helper/fileutil.inc index aae654bc..525e46a7 100644 --- a/helper/fileutil.inc +++ b/helper/fileutil.inc @@ -29,203 +29,4 @@ tarcopy () { [ "x${PS[1]}" != "x0" ] && perror "unpacking-part of tar-copy from '$SHORT' to '$TO' failed. (${PS[1]})" } -# get all files of required packages by a module -list_packet_files() { - [ -z "$REQUIRED_CONTENT_PACKAGES" ] && pinfo "No required packages for $TOOL" && return 1 - local PACKAGE="" - for PACKAGE in $REQUIRED_CONTENT_PACKAGES; do - local OPTIONAL="$(echo "$PACKAGE" | cut -c 1)" - [ "x$OPTIONAL" = "x@" ] && PACKAGE="$(echo "$PACKAGE" | cut -c 2-)" - local FILES="" - if [ "$PACKET_HANDLER" = "dpkg" ]; then - PACKAGECOMMAND="dpkg -L" - elif [ "$PACKET_HANDLER" = "rpm" ]; then - PACKAGECOMMAND="rpm -ql" - fi - if [ -n "$REQUIRED_PACKET_FILES_BLACKLIST" ]; then - FILES="$($PACKAGECOMMAND "$PACKAGE" | grep "^/" | \ - grep -v "$REQUIRED_PACKET_FILES_BLACKLIST" | \ - grep -v -E 'share/(man|doc)|/var/run|/var/log'; \ - echo ":###:${PIPESTATUS[0]}")" - else - FILES="$($PACKAGECOMMAND "$PACKAGE" | grep "^/" | grep -v -E 'share/(man|doc)|/var/run|/var/log'; echo ":###:${PIPESTATUS[0]}")" - fi -# FILES="$(rpm -ql "$PACKAGE" | grep "^/" | grep -v -E 'share/(man|doc)|/var/run|/var/log'; echo ":###:${PIPESTATUS[0]}")" - - # ugly hack to get our return value - #local LPRET=$(echo "$FILES" | tail -1 | sed 's/^.*:###:\([0-9]*\)$/\1/g') - #FILES=$(echo "$FILES" | sed 's/^\(.*\):###:[0-9]*$/\1/g') - local LPRET=$(echo "$FILES" | awk -F ':###:' '{printf $2}') - FILES=$(echo "$FILES" | awk -F ':###:' '{print $1}') - if [ "x$LPRET" != "x0" -a "x$OPTIONAL" != "x@" ]; then - pdebug "FILES: '$FILES'" - perror "dpkg/rpm exited with code '$LPRET' for required package ${PACKAGE}." - fi - [ "x$LPRET" != "x0" ] && pwarning "dpkg/rpm exited with code '$LPRET' for optional package ${PACKAGE}." && continue - [ -z "$FILES" ] && pwarning "list_packet_files empty for packet ${PACKAGE}." && continue - pdebug "Packet $PACKAGE has $(echo $FILES | wc -w) files..." - for FILE in $FILES; do - [ ! -d "$FILE" ] && echo "$FILE" - done - done -} -# -# Conveniance function -# -# install all dependencies of a module -# goes through all package as given in the variable REQUIRED_INSTALLED_PACKAGES -install_dependencies() { - [ -z "$REQUIRED_INSTALLED_PACKAGES" ] && return - install_packages "$REQUIRED_INSTALLED_PACKAGES" -} -# -# install given packet through system's packet manager -# uses PACKET_HANDLER as determined in helper/system.inc -# -install_packages() { - [ $# -eq 0 ] && perror "Sanity check failed: no argument given to install_package" - local PACKAGE_LIST="$@" - local INSTALLED_PACKAGES="" - - for PKG in ${PACKAGE_LIST}; do - # check if installed - if [ "x$PACKET_HANDLER" == "xdpkg" ]; then - dpkg -l ${PKG} > /dev/null 2>&1 - elif [ "x$PACKET_HANDLER" == "xrpm" ]; then - rpm -ql ${PKG} > /dev/null 2>&1 - else - perror "No packet manager / handler determined, this should not happen!" - fi - - local LRET=$? - if [ "x$LRET" == "x0" ]; then - # check if it is completly installed, - # not just leftover configuration files - local INSTALL_STATUS=$(dpkg -l $PKG | grep $PKG | cut -c1-2) - if [[ $INSTALL_STATUS != "ii" ]]; then - pinfo "$PKG not installed!" - install_package $PKG - else - # package installed - pdebug "$PKG installed!" - fi - else - # package not installed - pdebug "$PKG not installed!" - install_package $PKG - fi - done - [ ! -z "$INSTALLED_PACKAGES" ] && pinfo "Packages installed: ${INSTALLED_PACKAGES}" -} - -# -# install individual package depending on package manager -# -install_package() { - if [ "$#" -ne 1 ]; then - perror "Only call install_package with one argument!" - fi - - if [ "x$PACKET_MANAGER" == "xapt" ]; then - apt-get install -y ${PKG} - local IRET=$? - if [ "x$IRET" == "x0" ]; then - # $PGK was installed successfully - INSTALLED_PACKAGES+="$PKG " - else - # PKG was not installed - # TODO error handling - perror "install_packages: apt-get failed with '$IRET' for package '$PKG'" - fi - elif [ "x$PACKET_MANAGER" == "xzypper" ]; then - zypper --no-refresh --non-interactive install ${PKG} - local IRET=$? - if [ "x$IRET" == "x0" ]; then - # $PGK was installed successfully - INSTALLED_PACKAGES+="$PKG " - else - # PKG was not installed - # TODO error handling - perror "install_packages: zypper failed with '$IRET' for package '$PKG'" - fi - elif [ "x$PACKET_MANAGER" == "xyum" ]; then - yum --assumeyes install ${PKG} - local IRET=$? - if [ "x$IRET" == "x0" ]; then - # $PGK was installed successfully - INSTALLED_PACKAGES+="$PKG " - else - # PKG was not installed - # TODO error handling - perror "install_packages: yum failed with '$IRET' for package '$PKG'" - fi - else - perror "No packet manager determined, this should not happen!" - fi -} - -# -# copies static data files from /data/ to -# -copy_static_data() { - [ ! -d "${MODULE_DIR}/data" ] && pinfo "${MODULE} has no static 'data' directory." && return - cp -r "${MODULE_DIR}/data/"* ${TARGET_BUILD_DIR} || perror "Could not copy static data of ${MODULE}" -} - -copy_system_files() { - [ ! -z "$REQUIRED_SYSTEM_FILES" ] && tarcopy "$REQUIRED_SYSTEM_FILES" "$TARGET_BUILD_DIR" -} - -calc_size() { - - local CURRENT_BUILD_SIZE=$(du -bc "${TARGET_BUILD_DIR}" | awk 'END {print $1}') - - [ ! -z "${BUILD_SIZE[$MODULE]}" ] && local OLD_MODULE_SIZE=${BUILD_SIZE[$MODULE]} || local OLD_MODULE_SIZE=0 - local diff=$((CURRENT_BUILD_SIZE-TARGET_BUILD_SIZE+OLD_MODULE_SIZE)) - - if [ -z "${BUILD_SIZE[$MODULE]}" ]; then - echo "BUILD_SIZE[$MODULE]=${diff}" >> "${ROOT_DIR}/logs/${TARGET}.size" - else - sed -i "s/^BUILD_SIZE\[${MODULE}\]=.*$/BUILD_SIZE\[${MODULE}\]=${diff}/g" "${ROOT_DIR}/logs/${TARGET}.size" - fi - - MODULE_BUILD_SIZE=$(echo $diff | awk '{ sum=$1; hum[1024^3]="GB"; hum[1024^2]="MB"; hum[1024]="KB"; - for (x=1024^3; x>=1024; x/=1024){ - if (sum>=x) { printf "%.2f %s\n",sum/x,hum[x]; break } - } - }') -} - -# -# generate initramfs of directory -# usage: -# generate_initramfs -# example: -# generate_initramfs "./server/boot/stage32_sqfs" "./mnt/openslx.sqfs" "./server/boot/initramfs2" -# generate_initramfs "./server/build/stage31" "." "./server/boot/initramfs" -generate_initramfs() { - [ $# -ne 3 ] && perror "Sanity check failed: generate_initramfs needs exactly two params, but $# were given." - cd "$1" || perror "Cannot cd to '$1'" - - find $2 | cpio --format="newc" --create | gzip -9 > "$3" - local PS=(${PIPESTATUS[*]}) - [ "x${PS[0]}" != "x0" ] && perror "'find $2' in '$(pwd)' failed." - [ "x${PS[1]}" != "x0" ] && perror "cpio create failed." - [ "x${PS[2]}" != "x0" ] && perror "gzip to '$3' failed." - cd - &> /dev/null - pinfo "Created initramfs of $1 at $3" - pinfo "Size: $(du -bsh "$3" | awk 'END {print $1}')" -} - -# generates squashfs of directory -# usage: -# generate_squashfs -generate_squashfs() { - [ $# -ne 2 ] && perror "Sanity check failed: generate_squashfs needs exactly two params, but $# were given." - [ -d "$1" ] || perror "$1 is not a directory." - mksquashfs "$1" "$2" -comp xz -b 1M -no-recovery >&6 \ - || perror "mksquashfs failed ($?)." - pinfo "Created squashfs of $1 at $2" - pinfo "Size: $(du -bsh "$2" | awk 'END {print $1}')" -} diff --git a/helper/kernel.inc b/helper/kernel.inc deleted file mode 100644 index 61fa3efd..00000000 --- a/helper/kernel.inc +++ /dev/null @@ -1,178 +0,0 @@ -# -# Common functions to copy kernel related files -# -############################################################ -# -# -# copies kernel modules as given in the module config file -# * depends on 'depmod' -# * requires REQUIRED_KERNEL_MODULES to be set. -# (entries must be a relative path to /lib/modules/) -# -# ex: for /lib/modules/3.2.0/kernel/fs/nfs/nfs.ko -# must be given as kernel/fs/nfs/nfs.ko -# - -# this code depends on KERNEL_CURRENT_VERSION, this file needs to be sourced after helper/system.inc! -# (TODO: maybe source system.inc if KERNEL_CURRENT_VERSION -if [ -z "${KERNEL_CURRENT_VERSION}" ]; then - . ${ROOT_DIR}/helper/system.inc - [ -z "${KERNEL_CURRENT_VERSION}" ] && perror "KERNEL_CURRENT_VERSION still not set after sourcing, something is very wrong..." -fi - -# set global KERNEL_TARGET_NAME -KERNEL_TARGET_NAME="kernel" - -check_kernel_build_dir() { - [ -d "${MODULES_DIR}/kernel/build" ] && KERNEL_BUILD_DIR="${MODULES_DIR}/kernel/build" \ - || perror "No build directory set for the kernel. Was is built?" - # hack to get the real path of the installed modules - KERNEL_NEW_VERSION=$(ls ${KERNEL_BUILD_DIR}/lib/modules) -} - -copy_kernel_modules() { - pinfo "Copying kernel modules for kernel ${KERNEL_CURRENT_VERSION}..." - [ -z "${REQUIRED_KERNEL_MODULES}" ] && perror "REQUIRED_KERNEL_MODULES is empty. Check your config file." - check_kernel_build_dir - # - # process modules list - # - # search for modules in KERNEL_BUILD_DIR - cd "${KERNEL_BUILD_DIR}" || perror "Could not cd to ${KERNEL_BUILD_DIR}" - - local KERNEL_MODULES_DIR="lib/modules/${KERNEL_NEW_VERSION}" - local KERNEL_MODULES_LIST="" - local REQUIRED_KERNEL_MODULES_EXPANDED="" - local KERNEL_MODULE="" - local KERNEL_MODULE_PATH="" - local ELEM="" - - # Do some fancy stuff to allow wildcards etc. in required kernel modules. - cd "${KERNEL_MODULES_DIR}" - for KERNEL_MODULE in ${REQUIRED_KERNEL_MODULES}; do - for ELEM in $KERNEL_MODULE; do - echo $ELEM | grep '\*' && pwarning "Could not expand '$ELEM'." && continue - REQUIRED_KERNEL_MODULES_EXPANDED+=" $ELEM" - done - done - cd - - pinfo "Expanded the list of $(echo "$REQUIRED_KERNEL_MODULES" | wc -w) required kernel modules to $(echo "$REQUIRED_KERNEL_MODULES_EXPANDED" | wc -w)" - - for KERNEL_MODULE in ${REQUIRED_KERNEL_MODULES_EXPANDED}; do - local KERNEL_MODULE_PATH="${KERNEL_MODULES_DIR}/${KERNEL_MODULE}" - if grep "^${KERNEL_MODULE}$" "${KERNEL_BUILD_DIR}/${KERNEL_MODULES_DIR}/modules.builtin" >/dev/null; then - pdebug "Already built-in ${KERNEL_MODULE}." - elif [ -e "${KERNEL_MODULE_PATH}" ]; then - pdebug "Copying '${KERNEL_MODULE_PATH}'" - KERNEL_MODULES_LIST+=" ${KERNEL_MODULE_PATH}" - else - pwarning "Module ${KERNEL_MODULE} not found. Skipping. (might cause problems on certain clients!)" - continue - fi - - # check for dependencies - local DEPS=$(grep "${KERNEL_MODULE}:" "${KERNEL_BUILD_DIR}/${KERNEL_MODULES_DIR}/modules.dep" | cut -d ":" -f2-) - if [ ! -z "$DEPS" ]; then - for DEP in $DEPS; do - pdebug "Adding dep: ${KERNEL_MODULES_DIR}/$DEP" - KERNEL_MODULES_LIST+=" ${KERNEL_MODULES_DIR}/$DEP" - done - else - pdebug "${KERNEL_MODULE} has no dependencies." - fi - done - - if [ ! -z "${KERNEL_MODULES_LIST}" ]; then - local COUNT=$(echo "${KERNEL_MODULES_LIST}" | wc -w) - pinfo "Copying $COUNT modules to target directory." - tarcopy "${KERNEL_MODULES_LIST}" "${TARGET_BUILD_DIR}" - fi - - # - # generate modules map files - # - # first strip modules.order of all the modules we don't use - cat "${KERNEL_MODULES_DIR}/modules.order" | grep -E $(echo ${REQUIRED_KERNEL_MODULES} | tr '\ ' '|') \ - >> "${TARGET_BUILD_DIR}/${KERNEL_MODULES_DIR}/modules.order" - # copy list of builtin kernel modules - cp "${KERNEL_MODULES_DIR}/modules.builtin" "${TARGET_BUILD_DIR}/${KERNEL_MODULES_DIR}" - # with modules.order and modules.builtin, we can run depmod for the rest of the files - depmod -b "${TARGET_BUILD_DIR}" -a "${KERNEL_NEW_VERSION}" - - cd - >/dev/null -} - -copy_firmware() { - - pinfo "Copying firmware for kernel ${KERNEL_CURRENT_VERSION}..." - [ -z "${REQUIRED_FIRMWARE}" ] && perror "REQUIRED_FIRMWARE is empty. Check your config file." - local OLD_DIR=$(pwd) - check_kernel_build_dir - # - # process firmware list - # - cd "${KERNEL_BUILD_DIR}" || perror "Could not cd!" - local FIRMWARE_DIR="lib/firmware" - local FIRMWARE_LIST="" - for FIRMWARE in ${REQUIRED_FIRMWARE}; do - local FOUND=0 - # check for firmware in the build directory of the kernel - for CANDIDATE in "${FIRMWARE_DIR}/${FIRMWARE}" "${FIRMWARE_DIR}/${KERNEL_NEW_VERSION}/${FIRMWARE}"; do - if [ -e "${CANDIDATE}" ]; then - pdebug "Copying from kernel build dir: '${CANDIDATE}'" - FIRMWARE_LIST+=" ${CANDIDATE}" - FOUND=1 - fi - done - - # if we didn't found it in the kernel build directory, check for firmware in the system firmware directory - if [ $FOUND -ne 1 ]; then - for CANDIDATE in "/${FIRMWARE_DIR}/${FIRMWARE}" "/${FIRMWARE_DIR}/${KERNEL_CURRENT_VERSION}/${FIRMWARE}"; do - if [ -e "${CANDIDATE}" ]; then - if [ $(echo "${CANDIDATE}" | grep -c "${KERNEL_CURRENT_VERSION}") -eq 0 ]; then - pdebug "Copying from system: '${CANDIDATE}'" - FIRMWARE_LIST+=" ${CANDIDATE}" - else - pdebug "Copying from system: '${CANDIDATE}' to ${FIRMWARE_DIR}/${KERNEL_NEW_VERSION}/${FIRMWARE}" - FIRMWARE_LIST+=" /${FIRMWARE_DIR}/${KERNEL_CURRENT_VERSION}/${FIRMWARE}" - fi - FOUND=1 - fi - done - fi - - [ $FOUND -ne 1 ] && pwarning "Neither '${FIRMWARE_DIR}/${FIRMWARE}' nor '${FIRMWARE_DIR}/${KERNEL_NEW_VERSION}/${FIRMWARE}' "\ - " was found on the system. Skipping. (might cause problems on certain clients!)" - done - - if [ ! -z "${FIRMWARE_LIST}" ]; then - local COUNT=$(echo "${FIRMWARE_LIST}" | wc -w) - pinfo "Copying $COUNT firmware to target directory." - tarcopy "${FIRMWARE_LIST}" "${TARGET_BUILD_DIR}" - fi - - # post-process to fix the path of the firmwares found on the system unter /lib/firmware/$(uname -r) - # which have to be copied to /lib/firmware/${KERNEL_NEW_VERSION} - if [ -d "${TARGET_BUILD_DIR}/lib/firmware/${KERNEL_CURRENT_VERSION}" ]; then - mkdir -p "${TARGET_BUILD_DIR}/lib/firmware/${KERNEL_NEW_VERSION}/" - cd "${TARGET_BUILD_DIR}/lib/firmware/${KERNEL_CURRENT_VERSION}" || perror "old kernel but no old kernel" - tarcopy "$(ls)" "${TARGET_BUILD_DIR}/lib/firmware/${KERNEL_NEW_VERSION}/" - cd - - rm -r "${TARGET_BUILD_DIR}/lib/firmware/${KERNEL_CURRENT_VERSION}" || perror "something went very wrong..." - else - pdebug "No ${TARGET_BUILD_DIR}/lib/firmware/${KERNEL_CURRENT_VERSION} directory, skipping the merge." - fi - - cd "$OLD_DIR" -} - -copy_kernel() { - check_kernel_build_dir - - local TOOL_STR="$TOOL_STR copy_kernel:" - local KERNEL_DIR="${MODE_DIR}/builds/kernel" - pinfo "Copying '${KERNEL_TARGET_NAME}' to '${KERNEL_DIR}'." - [ -d "${KERNEL_DIR}" ] || mkdir -p "${KERNEL_DIR}" - cp "${KERNEL_BUILD_DIR}/${KERNEL_TARGET_NAME}" "${KERNEL_DIR}" || perror "Could not copy kernel!" - pinfo "You may want to update your systems firmware/modules to match the current kernel." -} diff --git a/helper/keyvalueutil.inc b/helper/keyvalueutil.inc deleted file mode 100644 index a0a89db7..00000000 --- a/helper/keyvalueutil.inc +++ /dev/null @@ -1,32 +0,0 @@ -# Helper file for managing key-value containing files -# There are some specialized conveinience functions here first -# that mostly just pass a predefined filename to the genric function -# at the end - -# Add the given environment variable to /etc/environment -add_env () { - [ $# -ne 2 ] && perror "Usage: $0 'key' 'value'" - [ -z "$1" ] && perror "$0: Empty key!" - add_key_value "/etc/environment" "$1" "$2" -} - -# -# Adds the given key-value-pair to a given file -# The file will be relative to the current target build dir, -# even if it starts with a slash. -# Will perror if the key already exists with a different value -add_key_value () { - [ $# -ne 3 ] && perror "Usage: $0 'file' 'key' 'value'" - [ -z "$TARGET_BUILD_DIR" ] && perror "No TARGET_BUILD_DIR set. Aborting for safety." - local FILE="$TARGET_BUILD_DIR/$1" - local KEY="$2" - local VALUE="$(echo "$3" | sed "s/'/\\\\'/g")" # \\\\\\\\\\\\\\\\\\\\\\ßß - if [ -s "$FILE" ]; then - local CURRENT="$(grep -E "^\s*$KEY=.*$" "$FILE" | awk -F '=' '{$1=""; printf $0}' | itrim)" - [ -n "$CURRENT" -a "'$VALUE'" != "$CURRENT" ] && perror "Cannot set $KEY to '$VALUE' as it is already set to $CURRENT" - [ -n "$CURRENT" ] && return 0 - fi - mkdir -p "$(dirname "$FILE")" - echo "$KEY='$VALUE'" >> "$FILE" -} - diff --git a/helper/string.inc b/helper/string.inc index 4c6b9778..75baf2ca 100644 --- a/helper/string.inc +++ b/helper/string.inc @@ -1,10 +1,10 @@ # usage: VAR=$(trim " string ") trim() { - local var=$1 - var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters - var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters - echo -n "$var" + local var=$1 + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" } # Inline version of trim, use when piping diff --git a/helper/system.inc b/helper/system.inc deleted file mode 100644 index 806799ad..00000000 --- a/helper/system.inc +++ /dev/null @@ -1,42 +0,0 @@ -# Helper to determine various system information - -# -# determine architecture triplet from the path of libc needed by the executing shell. -# please try not to use this to find/fetch libs in /lib or /usr/lib. -# Use ARCH_LIB_DIR, like "$ARCH_LIB_DIR/somefile.so" or "/usr$ARCH_LIB_DIR/somefile.so" -ARCH_TRIPLET=$(ldd $SHELL|grep "libc.so" | awk -F "/" '{print $3}') -#[ -z "$ARCH_TRIPLET" ] && pwarning "Could not determine arch triplet." -[[ $ARCH_TRIPLET == *\(*\) ]] && ARCH_TRIPLET="" - -ARCH_LIB_DIR=$(ldd $SHELL | grep "libc.so" | sed -r 's#^.*(/lib.*)/libc.so.*$#\1#g') -[ -z "$ARCH_LIB_DIR" -o ! -d "$ARCH_LIB_DIR" ] && perror "Could not determine arch dependent lib dir (where libc.so resides)" - -# determine kernel version -KERNEL_CURRENT_VERSION=$(uname -r) -[ ! -z $KERNEL_CURRENT_VERSION ] || pwarning "Could not determine kernel version." - -# determine number of CPU cores -CPU_CORES=$(cat /proc/cpuinfo | grep processor | wc -l) -export MAKEFLAGS="-j$CPU_CORES" - -# Determine if we have lib64 -if [ "$(uname -m)x" = "x86_64x" ]; then - # Setting LIB64, as openSuse differentiates but Ubuntu does not: - SYS_DISTRIBUTION=$(lsb_release -is | tr '[A-Z]' '[a-z]' | sed -r 's/[^a-z0-9]//g;s/project$//g;s/scientificsl$/scientific/g') - case $SYS_DISTRIBUTION in - ubuntu | debian) LIB64="lib" ;; - opensuse) LIB64="lib64" ;; - *) perror "Cannot set LIB64, SYS_DISTRIBUTION: $SYS_DISTRIBUTION unknown!" ;; - esac - AMD64_I386=amd64 - X86_64_I586=x86_64 - AMD64_X86=amd64 - ARCHREGEX="(amd64|x86[_-]64)" -else - LIB64="lib" - AMD64_I386=i386 - X86_64_I586=i586 - AMD64_X86=x86 - ARCHREGEX="(i[3456]86|x86[_-]32)" -fi - diff --git a/helper/useradd.inc b/helper/useradd.inc deleted file mode 100644 index 1e35c571..00000000 --- a/helper/useradd.inc +++ /dev/null @@ -1,215 +0,0 @@ -# Add a user to the system -# -# Usage: -# either do ID_OF_REQUESTED_USER=$(add_user herbert) -# or ID_OF_USER=$(USER=herbert GROUP=somegroup PASSWORD=secret123 add_user) -# Valid params are: -# USER, GROUP, USERID, GROUPID, PASSWORD, USERHOME, USERSHELL -# defaults are no password, home=/nonexistent, usershell=/bin/false -# IDs will be generated in the range of 5-999 if not explicitly given -# TODO: Make it possible to pass a range of IDs if you don't want one <1000 but don't care about the exact ID - -. "${ROOT_DIR}/helper/string.inc" - -NAME_REGEX='^[a-z][-a-z0-9]*$' - -# Generate a UID for a given USERNAME. Return existing UID if possible, generate new one otherwise -generate_uid() -{ - [ $# -ne 1 ] && perror "generate_uid fail. want 1 argument." - [ -z "${_PASSWD}" ] && perror "passwd file not set." - local _UID=$(grep -E "^$1:[^:]*:[0-9]+:" "${_PASSWD}" | head -1 | awk -F ':' '{print $3}') - if [ "x${_UID}" = "x" ] - then - local _TRIES=0 - while [ ${_TRIES} -lt 50 ] - do - _TRIES=$[ ${_TRIES} + 1 ] - _UID=$[ 5 + $RANDOM % 900 ] - local _TEST=$(grep -E "^[^:]+:[^:]*:${_UID}:" "${_PASSWD}") - [ "x${_TEST}" = "x" ] && break - done - [ ${_TRIES} -ge 50 ] && perror "Generating a UID failed." - fi - echo ${_UID} -} - -# Generate a GID for a given GROUPNAME. Return existing GID if possible, generate new one otherwise -generate_gid() -{ - [ $# -ne 2 ] && perror "generate_gid fail. want 2 arguments." - [ -z "${_GROUP}" ] && perror "group file not set." - local _GID=$(grep -E "^$1:[^:]*:[0-9]+:" "${_GROUP}" | head -1 | awk -F ':' '{print $3}') - if [ "x${_GID}" = "x" ] - then - # group does not exist, try to create - local _TRIES=0 - _GID=$2 # try to use uid as gid if not taken yet - while [ ${_TRIES} -lt 50 ] - do - _TRIES=$[ ${_TRIES} + 1 ] - local _TEST=$(grep -E "^[^:]+:[^:]*:${_GID}:" "${_GROUP}") - [ "x${_TEST}" = "x" ] && break - _GID=$[ 5 + $RANDOM % 900 ] # using uid as gid not possible, generate new one - done - [ ${_TRIES} -ge 50 ] && perror "Generating a GID failed." - fi - echo ${_GID} -} - -add_user() { - [ -z "${TARGET_BUILD_DIR}" ] && perror "add_user: TARGET_BUILD_DIR not set" - if [ -z $USER -a $# -eq 0 ] - then - pwarning " ** add_user usage **" - pwarning "add_user " - pwarning "OR" - pwarning "USER= [GROUP=] [USERID=] [GROUPID=] [USERHOME=] [USERSHELL=] [PASSWORD=] add_user" - perror "Aborting, please fix your script." - fi - local _PASSWD=${TARGET_BUILD_DIR}/etc/passwd - local _GROUP=${TARGET_BUILD_DIR}/etc/group - local _SHADOW=${TARGET_BUILD_DIR}/etc/shadow - init_users_and_groups - [ ! -f "${_PASSWD}" ] && perror "add_user: password file does not exist in target system. (build base first)" - [ ! -f "${_GROUP}" ] && perror "add_user: group file does not exist in target system. (build base first)" - [ ! -f "${_SHADOW}" ] && perror "add_user: shadow file does not exist in target system. (build base first)" - if [ "x$1" != "x" ] - then - local USER=$1 - local GROUP=$1 - local USERID="" - local GROUPID="" - local USERHOME="" - local USERSHELL="" - local PASSWORD="" - fi - USER=$(trim "$USER") - if ! [[ $USER =~ $NAME_REGEX ]]; then - perror "Invalid username: $USER" - fi - [ "x$GROUP" = "x" ] && local GROUP=$USER - GROUP=$(trim "$GROUP") - if ! [[ $GROUP =~ $NAME_REGEX ]]; then - perror "Invalid group: $GROUP" - fi - [ "x$USERID" = "x" ] && local USERID=$(generate_uid "${USER}") - USERID=$(trim "$USERID") - [ "$USERID" -lt "0" -o "$USERID" -gt "65535" ] && perror "Invalid userid: $USERID" - [ "x$GROUPID" = "x" ] && local GROUPID=$(generate_gid "${GROUP}" "${USERID}") - GROUPID=$(trim "$GROUPID") - [ "$GROUPID" -lt "0" -o "$GROUPID" -gt "65535" ] && perror "Invalid groupid: $GROUPID" - # all required variables have been set - # does the desired username already exist? if so, check if UID matches, otherwise bail out - local _UID=$(grep -E "^${USER}:[^:]*:[0-9]+:" "${_PASSWD}" | head -1 | awk -F ':' '{print $3}') - [ ! -z "${_UID}" ] && [ "x${_UID}" != "x${USERID}" ] && perror "User ${USER}(${USERID}) already exists with UID ${_UID}" - # do the same for the group - local _GID=$(grep -E "^${GROUP}:[^:]*:[0-9]+:" "${_GROUP}" | head -1 | awk -F ':' '{print $3}') - [ ! -z "${_GID}" ] && [ "x${_GID}" != "x${GROUPID}" ] && perror "Group ${GROUP}(${GROUPID}) already exists with GID ${_GID}" - # if user already exists, check if he is in another group than the one requested. if so, bail out - # (TODO: don't bail out and add user to the new group) - if [ ! -z "${_UID}" ] - then - local _EXGID=$(grep -E "^${USER}:[^:]*:[0-9]+:" "${_PASSWD}" | head -1 | awk -F ':' '{print $4}') - [ "x${GROUPID}" != "x${_EXGID}" ] && perror "Requested GID $GROUPID differs from existing GID $_EXGID" - fi - # if user does not exist, try to add it - if [ -z "${_UID}" ] - then - local _TEST=$(grep -E "^[^:]+:[^:]*:${USERID}:" "${_PASSWD}") - [ ! -z "${_TEST}" ] && perror "Cannot add $USER - desired UID $USERID already in use." - fi - if [ -z "${_GID}" ] - then - local _TEST=$(grep -E "^[^:]+:[^:]*:${GROUPID}:" "${_GROUP}") - [ ! -z "${_TEST}" ] && perror "Cannot add $GROUP - desired GID $GROUPID already in use." - fi - [ -z "${USERHOME}" ] && local USERHOME=/nonexistent - [ -z "${USERSHELL}" ] && local USERSHELL=/bin/false - # create password - if [ -z "${PASSWORD}" ] - then - local PASSWORD='*' - else - pdebug "Hashing password '$PASSWORD' for '$USER'" - local PW=$(mkpasswd -m sha-512 "${PASSWORD}") - [ -z "${PW}" ] && PW=$(openssl passwd -1 "${PASSWORD}") - [ -z "${PW}" ] && perror "Error generating hashed password for $USER" - PASSWORD=$PW - fi - # add user, or replace password - if [ -z "${_UID}" ]; then - # create user - echo "${USER}:x:${USERID}:${GROUPID}:${USER}:${USERHOME}:${USERSHELL}" >> "${_PASSWD}" - echo "${USER}:${PASSWORD}:15555:0:99999:7:::" >> "${_SHADOW}" - pinfo "Created user $USER" - elif [ "$PASSWORD" != "*" ]; then - # update user's password - sed -i -r "s#^${USER}:[^:]*:(.*)\$#${USER}:${PASSWORD}:\1#g" "${_SHADOW}" - pinfo "Updated password of $USER" - fi - [ -z "${_GID}" ] && pinfo "Created group $GROUP" && echo "${GROUP}:x:${GROUPID}:" >> "${_GROUP}" - echo "${USERID}" -} - -add_group () { - [ $# -lt 1 ] && perror "add_group called without argument." - [ -z "${TARGET_BUILD_DIR}" ] && perror "add_group: TARGET_BUILD_DIR not set" - local _PASSWD=${TARGET_BUILD_DIR}/etc/passwd - local _GROUP=${TARGET_BUILD_DIR}/etc/group - local _SHADOW=${TARGET_BUILD_DIR}/etc/shadow - init_users_and_groups - [ ! -f "${_GROUP}" ] && perror "add_user: group file does not exist in target system. (build base first)" - local GROUP=$1 - local GROUPID="-" - if ! [[ $GROUP =~ $NAME_REGEX ]]; then - perror "Invalid group: $GROUP" - fi - [ $# -ge 2 ] && [ ! -z "$2" ] && GROUPID=$2 - local _GID=$(grep -E "^${GROUP}:[^:]*:[0-9]+:" "${_GROUP}" | head -1 | awk -F ':' '{print $3}') - [ "x${_GID}" != "x" ] && [ "x$GROUPID" = "x-" -o "x$GROUPID" = "x${_GID}" ] && echo "${_GID}" && return # nothing to do, already exists - [ "x${_GID}" != "x" ] && perror "Group $GROUP already exists with GID ${_GID}, but creation was requested with GID $GROUPID" - if [ "x$GROUPID" = "x-" ]; then - local _UID=$(grep -E "^${GROUP}:[^:]*:[0-9]+:" "${_PASSWD}" | head -1 | awk -F ':' '{print $3}') - [ -z "${_UID}" ] && _UID=100 - GROUPID=$(generate_gid "$GROUP" "${_UID}") - fi - if ! [[ $GROUPID =~ [0-9]+ ]]; then - perror "add_group: GROUPID not numeric (is '$GROUPID')" - fi - echo "${GROUP}:x:${GROUPID}:" >> "${_GROUP}" - pinfo "Created group $GROUP" - echo "${GROUPID}" -} - -init_users_and_groups() { - [ -z "$TARGET_BUILD_DIR" -o "$TARGET_BUILD_DIR" == "/" ] && perror "Almost wrecked your local passwd, group and shadow file. phew." - local PASSWD="$TARGET_BUILD_DIR/etc/passwd" - local GROUP="$TARGET_BUILD_DIR/etc/group" - local SHADOW="$TARGET_BUILD_DIR/etc/shadow" - [ -s "${PASSWD}" -a -s "${GROUP}" -a -s "${SHADOW}" ] && return - pinfo "Creating users and groups based on local system...." - cp -a "/etc/passwd" "$PASSWD" || perror "Could not copy /etc/passwd" - cp -a "/etc/group" "$GROUP" || perror "Could not copy /etc/group" - cp -a "/etc/shadow" "$SHADOW" || perror "Could not copy /etc/shadow" - # make sure shadow has group shadow (should be handled by cp -a but hey) - chgrp shadow "$SHADOW" - # remove local users from group file (TODO: currently assumes users have ids 1000-1999) - local LOCALUSERS=$(grep -E '^[^:]+:x?:1[0-9]{3}:' "${PASSWD}" | awk -F ':' '{print $1}') - for USER in $LOCALUSERS; do - sed -r -i "s/([:,])${USER}/\1/g" "${GROUP}" - done - # fix syntax: remove trailing ',' in group file - sed -r -i 's/,+$//g' "${GROUP}" - sed -r -i 's/,+/,/g' "${GROUP}" - sed -i 's/:,/:/g' "${GROUP}" - # remove all non-system groups (also assumes users have 1000-1999, so nogroup will be kept) - grep -v -E '^[^:]+:x?:1[0-9]{3}:' "${GROUP}" > "${GROUP}.tmp" - mv "${GROUP}.tmp" "${GROUP}" - # same for users... - grep -v -E '^[^:]+:x?:1[0-9]{3}:' "${PASSWD}" > "${PASSWD}.tmp" - mv "${PASSWD}.tmp" "${PASSWD}" - # generate fresh shadow file - awk -F ':' '{print $1":*:15555:0:99999:7:::"}' "${PASSWD}" > "${SHADOW}" -} - -- cgit v1.2.3-55-g7522