Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 60 additions & 92 deletions build/rootfs/etc/cont-init.d/50-setup-ikvm.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,107 +1,75 @@
#!/bin/sh
# ipmikvm-tls2020 (part of ossobv/vcutil) // wdoekes/2020 // Public Domain
#
# A wrapper to call the SuperMicro iKVM console bypassing Java browser
# plugins.
#
# Requirements: base64, curl, java
#
# Usage:
#
# $ ipmikvm-tls2020
# Usage: ipmikvm-tls2020 [-u ADMIN] [-P ADMIN] IP.ADD.RE.SS
#
# $ ipmikvm-tls2020 10.11.12.13 -P otherpassword
# (connects KVM console on IPMI device at 10.11.12.13)
#
# This has been tested with iKVM__V1.69.39.0x0.
#
# See also: ipmikvm
#
set -e # Exit immediately if a command exits with a non-zero status
set -u # Treat unset variables as an error
set -e
set -u

APP_CACHE_DIR=$XDG_CACHE_HOME
CONT_ENV_DIR=/etc/cont-env.d

get_launch_jnlp() {
fail=1
url="https://$KVM_HOST"
temp=$(mktemp)
if curl --fail -sk --cookie-jar "$temp" -XPOST "$url/cgi/login.cgi" \
--data "name=$KVM_USER&pwd=$KVM_PASS&check=00" -o/dev/null; then
launch_jnlp=$(curl --fail -sk --cookie "$temp" \
--referer "$url/cgi/url_redirect.cgi?url_name=man_ikvm" \
"$url/cgi/url_redirect.cgi?url_name=man_ikvm&url_type=jwsk")
test $? -eq 0 && fail=
fi
rm "$temp"
test -z "$fail" && echo "$launch_jnlp"
}
url="${KVM_PROTOCOL:-https}://$KVM_HOST"
temp=$(mktemp)

echo "Connecting to $url..."

get_arguments() {
launch_jnlp="$1"
echo "$launch_jnlp" | sed -e '/<argument>/!d;s#.*<argument>\([^<]*\)</argument>.*#\1#' |
sed -e "s/['\"$]//g;s/.*/&/" | sed -e 1,4d
}
curl --fail -s --cookie-jar "$temp" -XPOST "$url/cgi/login.cgi" \
--data "name=$KVM_USER&pwd=$KVM_PASS&check=00" -o/dev/null

get_username() {
launch_jnlp="$1"
echo "$launch_jnlp" | sed -e '/<argument>/!d' |
sed -e '2!d;s#.*<argument>\([^<]*\)</argument>#\1#'
}
echo "Login successful, fetching JNLP..."
launch_jnlp=$(curl --fail -s --cookie "$temp" \
--referer "$url/cgi/url_redirect.cgi?url_name=man_ikvm" \
"$url/cgi/url_redirect.cgi?url_name=man_ikvm&url_type=jwsk")

get_password() {
launch_jnlp="$1"
echo "$launch_jnlp" | sed -e '/<argument>/!d' |
sed -e '3!d;s#.*<argument>\([^<]*\)</argument>#\1#'
}
echo "$launch_jnlp" > "$APP_CACHE_DIR/launch.jnlp"

get_app_class() {
echo "$1" | sed -ne 's/.*<application-desc .*main-class="\([^"]*\)".*/\1/p'
}
# Extract JAR names - use 32-bit native lib since container is linux/386
main_jar=$(echo "$launch_jnlp" | sed -n 's/.*<jar href="\([^"]*\.jar\)".*/\1/p' | head -1)
native_jar=$(echo "$launch_jnlp" | sed -n 's/.*href="\(liblinux_x86__[^"]*\.jar\)".*/\1/p' | head -1)

# SYNOPSIS: get_app_class JNLP_DATA
install_ikvm_application() {
launch_jnlp="$1"
destdir="$2"
echo "Main JAR: $main_jar"
echo "Native JAR (32-bit): $native_jar"

set -e
codebase=$(
echo "$launch_jnlp" | sed -e '/<jnlp /!d;s/.* codebase="//;s/".*//')
jar=$(
echo "$launch_jnlp" | sed -e '/<jar /!d;s/.* href="//;s/".*//')
linuxlibs=$(
echo "$launch_jnlp" |
sed -e '/<nativelib /!d;/linux.*x86__/!d;s/.* href="//;s/".*//' |
sort -u)
set -x
mkdir -p "$destdir"
cd "$destdir"
for x in $jar $linuxlibs; do
curl -ko $x.pack.gz "$codebase$x.pack.gz"
unpack200 $x.pack.gz $x
done
unzip -o liblinux*.jar
rm -rf META-INF
set +x
set +e
}
cd "$APP_CACHE_DIR"

# Download and decompress main JAR (two-step: gunzip then unpack200)
echo "Downloading ${main_jar}.pack.gz..."
curl -s --cookie "$temp" "$url/${main_jar}.pack.gz" -o "${main_jar}.pack.gz"
gunzip -f "${main_jar}.pack.gz" 2>/dev/null || true
if [ -f "${main_jar}.pack" ]; then
unpack200 "${main_jar}.pack" "$main_jar"
rm -f "${main_jar}.pack"
fi

JNLP=$(get_launch_jnlp "$KVM_HOST" "$KVM_USER" "$KVM_PASS")
test -z "$JNLP" && echo "Failed to get launch.jnlp" >&2 && exit 1
if [ ! -f "$main_jar" ] || [ $(stat -c%s "$main_jar") -lt 1000 ]; then
echo "ERROR: Failed to download main JAR"
exit 1
fi
echo "Main JAR: $(stat -c%s "$main_jar") bytes"

JAR=$(find $APP_CACHE_DIR -name 'iKVM*.jar' | sort | tail -n1)
if ! test -f "$JAR"; then
install_ikvm_application "$JNLP" "$APP_CACHE_DIR"
JAR=$(find $APP_CACHE_DIR -name 'iKVM*.jar' | sort | tail -n1)
if ! ls -l "$JAR"; then
echo "Install failure" >&2
exit 1
# Download and decompress 32-bit native lib
if [ -n "$native_jar" ]; then
echo "Downloading ${native_jar}.pack.gz..."
curl -s --cookie "$temp" "$url/${native_jar}.pack.gz" -o "${native_jar}.pack.gz"
gunzip -f "${native_jar}.pack.gz" 2>/dev/null || true
if [ -f "${native_jar}.pack" ]; then
unpack200 "${native_jar}.pack" "$native_jar"
rm -f "${native_jar}.pack"
fi
# Extract .so files
if [ -f "$native_jar" ]; then
unzip -o "$native_jar" "*.so" 2>/dev/null || true
ls -la *.so 2>/dev/null || echo "No .so files extracted"
fi
fi

echo $JAR > /etc/cont-env.d/KVM_JAR_FILE
echo $(get_username "$JNLP") > /etc/cont-env.d/KVM_EPHEMERAL_USERNAME
echo $(get_password "$JNLP") > /etc/cont-env.d/KVM_EPHEMERAL_PASSWORD
echo $(get_app_class "$JNLP") > /etc/cont-env.d/KVM_JAR_APPCLASS
echo $(get_arguments "$JNLP") > /etc/cont-env.d/KVM_LAUNCH_ARGUMENTS
# Extract arguments from JNLP
main_class=$(echo "$launch_jnlp" | sed -n 's/.*main-class="\([^"]*\)".*/\1/p')
arguments=$(echo "$launch_jnlp" | sed -n 's/.*<argument>\([^<]*\)<\/argument>.*/\1/p' | tr '\n' ' ')

# Create environment files
echo "$APP_CACHE_DIR/$main_jar" > "$CONT_ENV_DIR/KVM_JAR_FILE"
echo "$main_class" > "$CONT_ENV_DIR/KVM_JAR_APPCLASS"
echo "$KVM_USER" > "$CONT_ENV_DIR/KVM_EPHEMERAL_USERNAME"
echo "$KVM_PASS" > "$CONT_ENV_DIR/KVM_EPHEMERAL_PASSWORD"
echo "$arguments" > "$CONT_ENV_DIR/KVM_LAUNCH_ARGUMENTS"

echo "Setup complete!"
rm "$temp"
15 changes: 14 additions & 1 deletion build/rootfs/startapp.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
#!/bin/sh

exec java $JAVA_OPTS -cp "$(cat /etc/cont-env.d/KVM_JAR_FILE)" $(cat /etc/cont-env.d/KVM_JAR_APPCLASS) $KVM_HOST $(cat /etc/cont-env.d/KVM_EPHEMERAL_USERNAME) $(cat /etc/cont-env.d/KVM_EPHEMERAL_PASSWORD) null $(cat /etc/cont-env.d/KVM_LAUNCH_ARGUMENTS)
JAR_FILE=$(cat /etc/cont-env.d/KVM_JAR_FILE)
MAIN_CLASS=$(cat /etc/cont-env.d/KVM_JAR_APPCLASS)
ARGS=$(cat /etc/cont-env.d/KVM_LAUNCH_ARGUMENTS)

export LD_LIBRARY_PATH="$XDG_CACHE_HOME:$LD_LIBRARY_PATH"

echo "Starting KVM..."
echo " JAR: $JAR_FILE"
echo " Class: $MAIN_CLASS"
echo " Args: $ARGS"

exec java $JAVA_OPTS \
-Djava.library.path="$XDG_CACHE_HOME" \
-cp "$JAR_FILE" $MAIN_CLASS $ARGS