diff options
author | Jonathan Bauer | 2015-05-27 18:24:18 +0200 |
---|---|---|
committer | Jonathan Bauer | 2015-05-27 18:24:18 +0200 |
commit | 578deaa14ca89020487ecadeb0982e7a3d433545 (patch) | |
tree | a1445b946059b2c6ec0066946b013c8e481be6b7 | |
parent | restructuring & bit of documentation ;) (diff) | |
download | systemd-init-578deaa14ca89020487ecadeb0982e7a3d433545.tar.gz systemd-init-578deaa14ca89020487ecadeb0982e7a3d433545.tar.xz systemd-init-578deaa14ca89020487ecadeb0982e7a3d433545.zip |
DO NOT USE YET. YOU'VE BEEN WARNED!!111
-rwxr-xr-x | mltk-ng | 66 | ||||
-rwxr-xr-x | mltk-ng.functions | 138 |
2 files changed, 204 insertions, 0 deletions
diff --git a/mltk-ng b/mltk-ng new file mode 100755 index 00000000..74503307 --- /dev/null +++ b/mltk-ng @@ -0,0 +1,66 @@ +#!/bin/bash +# ------------------------------------------------------------------------------ +# +# Mini-Linux Toolkit Next Gen +# +# ------------------------------------------------------------------------------ + +declare -rg ARG0="$0" +declare -rg SELF="$(readlink -f "$ARG0")" +declare -rg ROOT_DIR="$(dirname "${SELF}")" +declare -rg MLTK_PID="$$" + +banner() { + echo -e "\033[38;5;202m\t __ __ __ " + echo -e "\033[38;5;202m\t.--------.| | | |_| |--." + echo -e "\033[38;5;208m\t| || |_| _| < " + echo -e "\033[38;5;214m\t|__|__|__||____|____|__|__|" + echo -e "\033[38;5;214m\t " + echo -e "\033[38;5;220m\t ** OpenSLX Project // 2015 **" + echo -e "\033[38;5;226m\t http://lab.openslx.org/" + echo -e "\033[00m" +} + + +pinfo() { + echo -e "\033[38;5;10m[info]\033[0m $@" +} + +perror() { + echo -e "\033[38;5;9m[error]\033[0m $@" + kill "$MLTK_PID" + exit 1 +} + +print_usage() { + perror "./mltk-ng <remote_ip> <stage4_sync_dir> <target_qcow2_container>" +} + +# root check +if [ "$(id -u)" -ne 0 ]; then + perror "ERROR: You need to be root to use this toolkit." +else + banner +fi + +# do we even have tools? +for TOOL in qemu-img qemu-nbd mkfs.ext4; do + which $TOOL &>/dev/null || perror "Could not find '$TOOL'." +done + +# let's keep it simple for now, just source our main functions file +. ${ROOT_DIR}/mltk-ng.functions || perror "Could not source functions." + +# ok, now check that we have 3 args +[ $# -ne 3 ] && print_usage + +# even though functions check their parameter, we also do it to be safe. +valid_ip "$1" || perror "'$1' is not a valid IP adress, aborting..." +[ ! -d "$2" ] || perror "'$2' already exists, aborting..." +[ ! -f "$3" ] || perror "'$3' already exists, aborting..." + +# all good, let's start +pinfo " ## RUNNING ##" +clone_stage4 $1 $2 +export_qcow2 $2 $3 +pinfo " ## COMPLETE ##" diff --git a/mltk-ng.functions b/mltk-ng.functions new file mode 100755 index 00000000..363c16d8 --- /dev/null +++ b/mltk-ng.functions @@ -0,0 +1,138 @@ +# ------------------------------------------------------------------------------ +# +# Functions for MLTK-NG +# +# ------------------------------------------------------------------------------ +# +# check if we have mltk-ng environement variables to check +# if we actually got sourced by it. +if [ -z "${MLTK_PID}" -o -z "${ROOT_DIR}" ]; then + # not using perror, since we probably don't have it. + echo "Neither MLTK_PID nor ROOT_DIR is set. Was this included by mltk-ng?" + exit 1 +fi + +# Helper to generate a stage4 export for a remote machine per rsync. +clone_stage4() { + [ $# -ne 2 ] && perror "$0 <remote_ip> <stage4_sync_dir>" + local REMOTE_HOST="$1" + local TARGET_DIR="$2" + local BUILD_DIR="${ROOT_DIR}/builds/$REMOTE_HOST" + mkdir -p "$TARGET_DIR" + mkdir -p "$BUILD_DIR" + + local EXCLUDE="$BUILD_DIR/exclude-stage4" + local INCLUDE="$BUILD_DIR/include-stage4" + + pinfo "Building rsync exclude-file for building stage 4...." + echo "## Exclude file for stage4 of $REMOTE_HOST" > "$EXCLUDE" + echo "## Include file for stage4 of $REMOTE_HOST" > "$INCLUDE" + for FILE in $(find "$ROOT_DIR"/blacklists/*/ -type f); do + echo "## From $FILE" >> "$EXCLUDE" + echo "## From $FILE" >> "$INCLUDE" + grep '^-' "$FILE" >> "$EXCLUDE" + grep '^+' "$FILE" >> "$INCLUDE" + done + pinfo "Done." + + # prepare rsync's options + local RSYNC_SOURCE="root@$REMOTE_HOST:/" + local RSYNC_OPTS="-e ssh -c arcfour -oStrictHostKeyChecking=no" + + # run rsync with the exclude/include lists created earlier + pinfo "Cloning via rsync..." + cat "$INCLUDE" "$EXCLUDE" | \ + rsync --verbose \ + --archive \ + --delete \ + --delete-excluded \ + --numeric-ids \ + --exclude-from=- \ + "${RSYNC_OPTS}" \ + "${RSYNC_SOURCE}" \ + "${TARGET_DIR}" \ + || perror "rsync from '${RSYNC_SOURCE}' to '${TARGET_DIR}' failed." + pinfo "Cloning '${REMOTE_HOST}' to '${TARGET_DIR}' succeeded." + return 0 +} +# helper to build a qcow2 container from a stage4 sync directory. +# required tools: qemu-img, qemu-nbd, nbd, mkfs.ext4 +export_qcow2() { + # enough args? + [ $# -ne 2 ] && perror "Usage: $0 <stage4_synced_dir> <target_file>" + # $1 valid? + [ ! -d $1 ] && perror "First argument not a directory!" + # $2 should not be a dir or strange things will happen... + [ -d $2 ] && perror "Target file can not be a directory!" + + # $1 is dir, strip trailing slash if there is one + local STAGE4_DIR="${1%/}" + local TARGET_FILE="$2" + if [ -e $TARGET_FILE ]; then + pinfo "Removing old target: $TARGET_FILE" + rm $target || perror "Could not remove '$TARGET_FILE'" + fi + + # so far so good + pinfo "Creating empty qcow2-container ..." + qemu-img create -f qcow2 $TARGET_FILE 10G \ + || perror "qemu-img create failed with: $?" + pinfo "Done." + + # find usable nbd device + pinfo "Looking for usable nbd device..." + local NBD_ID="$(find_free_nbd)" + local NBD_DEV="/dev/nbd${NBD_ID}" + [ -b "$NBD_DEV" ] || perror "'$NBD_DEV' is not a block device!" + pinfo "Exporting '${TARGET_FILE}' using '${NBD_DEV}'..." + qemu-nbd -c ${NBD_DEV} ${TARGET_FILE} || perror "qemu-nbd failed with: $?" + pinfo "Done." + + pinfo "Creating ext4 filesystem on '${TARGET_FILE}'..." + mkfs.ext4 "${NBD_DEV}" || perror "mkfs failed with: $?" + pinfo "Done." + + # mount NBD_DEV + mkdir ${BUILD_DIR}/mnt + pinfo "Mounting '${NBD_DEV}' to '${BUILD_DIR}/mnt'..." + mount ${NBD_DEV} ${BUILD_DIR}/mnt || perror "Mount failed with: $?" + pinfo "Done." + + # copy files from the stage4 directory to the mounted qcow2-container + pinfo "Copying '${STAGE4_DIR}' to '${BUILD_DIR}/mnt'..." + cp -ra "${STAGE4_DIR}"/* "${BUILD_DIR}"/mnt || perror "Copying failed with: $?" + pinfo "Done." + + pinfo "Cleaning up..." + umount "${BUILD_DIR}/mnt" || perror "Could not unmount '${BUILD_DIR}/mnt'." + qemu-nbd -d /dev/nbd${nbd_id} || perror "Could not disconnect '${NBD_DEV}'." + pinfo "Exporting '${STAGE4_DIR}' to '${TARGET_FILE}' completed." +} + +# helper to find an unused nbd device +find_free_nbd() { + local nbd_size=0 + for nbd_id in {0..15}; do + [ -b "/dev/nbd${nbd_id}" ] || continue + [ ! -e "/sys/block/nbd${nbd_id}/size" ] || continue + nbd_size=$(cat /sys/block/nbd${nbd_id}/size) + [ $nbd_size -eq 0 ] && break + done + return ${nbd_id} +} +# helper to validate an ip +valid_ip() { + local ip=$1 + local stat=1 + + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + OIFS=$IFS + IFS='.' + ip=($ip) + IFS=$OIFS + [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ + && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] + stat=$? + fi + return $stat +} |