<commit_before># This file contains bash functions that are used by osbash on the host.

source "$LIB_DIR/functions.sh"

#-------------------------------------------------------------------------------
# Conditional execution
#-------------------------------------------------------------------------------
# TODO: Create a help function and display it under help by default or with
# option --help (-h).
# exec_cmd is used for conditional execution:
#
# OSBASH=exec_cmd
#
# Execute command only if OSBASH is set:
# ${OSBASH:-:} cmd args
#
# Execute command only if OSBASH is not set:
# ${OSBASH:+:} cmd args
#
# Disable actual call to VBoxManage (selectively override configuration):
# OSBASH= cmd args
#
# Enable call to VBoxManage (selectively override configuration):
# OSBASH=exec_cmd cmd args

function exec_cmd {
    local cmd=$1
    shift
    $cmd "$@"
}

#-------------------------------------------------------------------------------
function get_base_disk_name {
    echo "base-$VM_ACCESS-$OPENSTACK_RELEASE-$DISTRO"
}

# From DISTRO string (e.g., ubuntu-14.04-server-amd64), get first component
function get_distro_name {
    # Match up to first dash
    local re='([^-]*)'

    if [[ $DISTRO =~ $re ]]; then
        echo "${BASH_REMATCH[1]}"
    fi
}

#-------------------------------------------------------------------------------
# Networking
#-------------------------------------------------------------------------------

function create_host_networks {
    get_host_network_config

    local index
    for index in "${!NET_NAME[@]}"; do
        create_network $index
    done
}

function configure_node_netifs {
    local vm_name=$1

    get_node_netif_config "$vm_name"

    local index
    local type
    for index in "${!NODE_IF_TYPE[@]}"; do
        type=${NODE_IF_TYPE[index]}
        if [ "$type" = "dhcp" ]; then
            vm_nic_base "$vm_name" $index
        elif [ "$type" = "static" ]; then
            vm_nic_std "$vm_name" $index
        else
            echo >&2 "ERROR Unknown interface type: $type."
            exit 1
        fi
    done
}

#-------------------------------------------------------------------------------
# ssh
#-------------------------------------------------------------------------------

# Check permission for osbash insecure private key
function check_osbash_private_key {
    local key_name="osbash_key"
    local osbash_key_dir=$LIB_DIR/osbash-ssh-keys
    local osbash_key_path=$osbash_key_dir/$key_name

    if ! ls -l "$osbash_key_path"|grep -q "^-r--------"; then
        echo "Adjusting permissions for $osbash_key_path"
        chmod 400 "$osbash_key_path"
    fi
}

function strip_top_dir {
    local full_path=$1
    echo "${full_path/$TOP_DIR\//}"
}

# Copy files or directories to VM (incl. implied directories; HOME is TOP_DIR)
function vm_scp_to_vm {
    local ssh_port=$1
    shift
    local ssh_ip=${SSH_IP:=127.0.0.1}

    check_osbash_private_key

    while (($#)); do
        local src_path=$1
        shift
        local target_path=$(strip_top_dir "$src_path")
        local target_dir=$(dirname "$target_path")
        vm_ssh "$ssh_port" "mkdir -p $target_dir"
        scp -q -r \
            -i "$LIB_DIR/osbash-ssh-keys/osbash_key" \
            -o "UserKnownHostsFile /dev/null" \
            -o "StrictHostKeyChecking no" \
            -P "$ssh_port" \
            "$src_path" "$VM_SHELL_USER@$ssh_ip:$target_path"
    done
}

# Execute commands via ssh
function vm_ssh {
    local ssh_port=$1
    shift
    local ssh_ip=${SSH_IP:=127.0.0.1}

    check_osbash_private_key

    # Some operating systems (e.g., Mac OS X) export locale settings to the
    # target that cause some Python clients to fail. Override with a standard
    # setting (LC_ALL=C).
    LC_ALL=C ssh -q \
        -i "$LIB_DIR/osbash-ssh-keys/osbash_key" \
        -o "UserKnownHostsFile /dev/null" \
        -o "StrictHostKeyChecking no" \
        -p "$ssh_port" \
        "$VM_SHELL_USER@$ssh_ip" "$@"
}

function wait_for_ssh {
    local ssh_port=$1

    echo -e -n "${CStatus:-}Waiting for ssh server to respond on ${CData:-}${SSH_IP:-127.0.0.1}:$ssh_port${CReset:-}."
    while [ : ]; do
        if vm_ssh "$ssh_port" exit ; then
            break
        else
            echo -n .
            sleep 1
        fi
    done
    echo
}

# Copy one script to VM and execute it via ssh; log output to separate file
function ssh_exec_script {
    local ssh_port=$1
    local script_path=$2

    vm_scp_to_vm "$ssh_port" "$script_path"

    local remote_path=$(strip_top_dir "$script_path")

    echo -en "\n$(date) start $remote_path"

    local script_name=$(basename "$script_path" .sh)
    local prefix=$(get_next_prefix "$LOG_DIR" "auto")
    local log_path=$LOG_DIR/${prefix}_${script_name}.auto

    local rc=0
    vm_ssh "$ssh_port" "bash $remote_path && rm -vf $remote_path" \
        > "$log_path" 2>&1 || rc=$?
    if [ $rc -ne 0 ]; then
        echo >&2
        echo -e "${CError:-}ERROR: ssh returned status ${CData:-}$rc${CError:-} for${CData:-} $remote_path${CReset:-}" |
            tee >&2 -a "$LOG_DIR/error.log"
        touch "$STATUS_DIR/error"
        return $rc
    fi

    echo -en "\n$(date)  done"
}

# Wait for sshd, prepare autostart dirs, and execute autostart scripts on VM
function ssh_process_autostart {
    local vm_name=$1

    # Run this function in sub-shell to protect our caller's environment
    # (which might be _our_ enviroment if we get called again)
    (
    source "$CONFIG_DIR/config.$vm_name"

    local ssh_port
    if [ ${PROVIDER:-""} = virtualbox ]; then
        ssh_port=$VM_SSH_PORT
    else
        ssh_port=22
    fi

    wait_for_ssh "$ssh_port"
    vm_ssh "$ssh_port" "rm -rf lib config autostart"
    vm_scp_to_vm "$ssh_port" "$TOP_DIR/lib" "$TOP_DIR/config"

    local script_path=""
    for script_path in "$AUTOSTART_DIR/"*.sh; do<commit_msg>Fix IP address changes with KVM<commit_after># This file contains bash functions that are used by osbash on the host.

source "$LIB_DIR/functions.sh"

#-------------------------------------------------------------------------------
# Conditional execution
#-------------------------------------------------------------------------------
# TODO: Create a help function and display it under help by default or with
# option --help (-h).
# exec_cmd is used for conditional execution:
#
# OSBASH=exec_cmd
#
# Execute command only if OSBASH is set:
# ${OSBASH:-:} cmd args
#
# Execute command only if OSBASH is not set:
# ${OSBASH:+:} cmd args
#
# Disable actual call to VBoxManage (selectively override configuration):
# OSBASH= cmd args
#
# Enable call to VBoxManage (selectively override configuration):
# OSBASH=exec_cmd cmd args

function exec_cmd {
    local cmd=$1
    shift
    $cmd "$@"
}

#-------------------------------------------------------------------------------
function get_base_disk_name {
    echo "base-$VM_ACCESS-$OPENSTACK_RELEASE-$DISTRO"
}

# From DISTRO string (e.g., ubuntu-14.04-server-amd64), get first component
function get_distro_name {
    # Match up to first dash
    local re='([^-]*)'

    if [[ $DISTRO =~ $re ]]; then
        echo "${BASH_REMATCH[1]}"
    fi
}

#-------------------------------------------------------------------------------
# Networking
#-------------------------------------------------------------------------------

function create_host_networks {
    get_host_network_config

    local index
    for index in "${!NET_NAME[@]}"; do
        create_network $index
    done
}

function configure_node_netifs {
    local vm_name=$1

    get_node_netif_config "$vm_name"

    local index
    local type
    for index in "${!NODE_IF_TYPE[@]}"; do
        type=${NODE_IF_TYPE[index]}
        if [ "$type" = "dhcp" ]; then
            vm_nic_base "$vm_name" $index
        elif [ "$type" = "static" ]; then
            vm_nic_std "$vm_name" $index
        else
            echo >&2 "ERROR Unknown interface type: $type."
            exit 1
        fi
    done
}

#-------------------------------------------------------------------------------
# ssh
#-------------------------------------------------------------------------------

# Check permission for osbash insecure private key
function check_osbash_private_key {
    local key_name="osbash_key"
    local osbash_key_dir=$LIB_DIR/osbash-ssh-keys
    local osbash_key_path=$osbash_key_dir/$key_name

    if ! ls -l "$osbash_key_path"|grep -q "^-r--------"; then
        echo "Adjusting permissions for $osbash_key_path"
        chmod 400 "$osbash_key_path"
    fi
}

function strip_top_dir {
    local full_path=$1
    echo "${full_path/$TOP_DIR\//}"
}

# Copy files or directories to VM (incl. implied directories; HOME is TOP_DIR)
function vm_scp_to_vm {
    local ssh_port=$1
    shift
    local ssh_ip=${SSH_IP:=127.0.0.1}

    check_osbash_private_key

    while (($#)); do
        local src_path=$1
        shift
        local target_path=$(strip_top_dir "$src_path")
        local target_dir=$(dirname "$target_path")
        vm_ssh "$ssh_port" "mkdir -p $target_dir"
        scp -q -r \
            -i "$LIB_DIR/osbash-ssh-keys/osbash_key" \
            -o "UserKnownHostsFile /dev/null" \
            -o "StrictHostKeyChecking no" \
            -P "$ssh_port" \
            "$src_path" "$VM_SHELL_USER@$ssh_ip:$target_path"
    done
}

# Execute commands via ssh
function vm_ssh {
    local ssh_port=$1
    shift
    local ssh_ip=${SSH_IP:=127.0.0.1}

    check_osbash_private_key

    # Some operating systems (e.g., Mac OS X) export locale settings to the
    # target that cause some Python clients to fail. Override with a standard
    # setting (LC_ALL=C).
    LC_ALL=C ssh -q \
        -i "$LIB_DIR/osbash-ssh-keys/osbash_key" \
        -o "UserKnownHostsFile /dev/null" \
        -o "StrictHostKeyChecking no" \
        -p "$ssh_port" \
        "$VM_SHELL_USER@$ssh_ip" "$@"
}

function wait_for_ssh {
    local ssh_port=$1

    echo -e -n "${CStatus:-}Waiting for ssh server to respond on ${CData:-}${SSH_IP:-127.0.0.1}:$ssh_port${CReset:-}."
    while [ : ]; do
        if vm_ssh "$ssh_port" exit ; then
            break
        else
            echo -n .
            sleep 1
        fi
    done
    echo
}

# Copy one script to VM and execute it via ssh; log output to separate file
function ssh_exec_script {
    local ssh_port=$1
    local script_path=$2

    vm_scp_to_vm "$ssh_port" "$script_path"

    local remote_path=$(strip_top_dir "$script_path")

    echo -en "\n$(date) start $remote_path"

    local script_name=$(basename "$script_path" .sh)
    local prefix=$(get_next_prefix "$LOG_DIR" "auto")
    local log_path=$LOG_DIR/${prefix}_${script_name}.auto

    local rc=0
    vm_ssh "$ssh_port" "bash $remote_path && rm -vf $remote_path" \
        > "$log_path" 2>&1 || rc=$?
    if [ $rc -ne 0 ]; then
        echo >&2
        echo -e "${CError:-}ERROR: ssh returned status ${CData:-}$rc${CError:-} for${CData:-} $remote_path${CReset:-}" |
            tee >&2 -a "$LOG_DIR/error.log"
        touch "$STATUS_DIR/error"
        return $rc
    fi

    echo -en "\n$(date)  done"
}

# Wait for sshd, prepare autostart dirs, and execute autostart scripts on VM
function ssh_process_autostart {
    local vm_name=$1

    # Run this function in sub-shell to protect our caller's environment
    # (which might be _our_ enviroment if we get called again)
    (
    source "$CONFIG_DIR/config.$vm_name"
    ssh_env_for_node "$vm_name"

    local ssh_port
    if [ ${PROVIDER:-""} = virtualbox ]; then
        ssh_port=$VM_SSH_PORT
    else
        ssh_port=22
    fi

    wait_for_ssh "$ssh_port"
    vm_ssh "$ssh_port" "rm -rf lib config autostart"
    vm_scp_to_vm "$ssh_port" "$TOP_DIR/lib" "$TOP_DIR/config"

    local script_path=""
    for script_path in "$AUTOSTART_DIR/"*.sh; do
{'fraction_non_alphanumeric': 0.20358416850687958, 'fraction_numerical': 0.008323424494649227, 'mean_word_length': 1.9466966966966968, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 6, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6527313', 'n_tokens_mistral': 3906, 'n_tokens_neox': 3680, 'n_words': 1002}