diff options
Diffstat (limited to 'core')
238 files changed, 6339 insertions, 944 deletions
diff --git a/core/README.core b/core/README.core new file mode 100644 index 00000000..975ea975 --- /dev/null +++ b/core/README.core @@ -0,0 +1,2 @@ +Latest merge with 'git.openslx.org/openslx-ng/tm-scripts' on 23.12.16 +Commit: f5a59daf8d70a9027118292cd40b18c221897408 diff --git a/core/README.remote b/core/README.remote deleted file mode 100644 index e69de29b..00000000 --- a/core/README.remote +++ /dev/null diff --git a/core/bin/setup_target b/core/bin/setup_target index 865cf22d..f8f90801 100755 --- a/core/bin/setup_target +++ b/core/bin/setup_target @@ -375,7 +375,7 @@ process_module() { mkdir -p "${TARGET_BUILD_DIR}/opt/openslx/.mltk" if [ ! -d "${MODULE_DIR}" ]; then if [ -z "$DEPOF" ]; then - perror "Module directory for '$MODULE' not found in ${TAREGET_DIR}" + perror "Module directory for '$MODULE' not found in ${TARGET_DIR}" fi perror "Module directory for '$MODULE' not found in ${TARGET_DIR} (is a dependency of${DEPOF})" return @@ -435,7 +435,7 @@ process_module() { get_kernel_version # Execute load-hook before anything else module_load - cd "${MODULE_WORK_DIR}" || perror "cd to '${MODULE_WORK_DIR}' failed." + cd "${MODULE_WORK_DIR}" || perror "cd to '${MODULE_WORK_DIR}' failed." # Fetch source code if [ ! -e "$SOURCE_FLAG" ]; then pinfo "## Fetching source" @@ -498,7 +498,9 @@ clean_modules() { TARGET=$1 shift - TARGET_DIR="$(target_path ${TARGET})" + # TODO: what was the idea of target path? presumably something to do with the 'overlays' folder? + #TARGET_DIR="$(target_path ${TARGET})" + TARGET_DIR="${CORE_DIR}/targets/${TARGET}" TARGET_BUILD_DIR="${ROOT_DIR}/var/builds/${TARGET}" [ -d $TARGET_DIR ] || perror "Given target directory does not exist: $TARGET_DIR" diff --git a/core/modules/alsa/data/opt/openslx/scripts/alsa-default_card b/core/modules/alsa/data/opt/openslx/scripts/alsa-default_card index 214a4d73..1e28aa4c 100755 --- a/core/modules/alsa/data/opt/openslx/scripts/alsa-default_card +++ b/core/modules/alsa/data/opt/openslx/scripts/alsa-default_card @@ -1,5 +1,4 @@ #!/bin/ash -PATH=$PATH:/opt/openslx/sbin:/opt/openslx/bin PROC="/proc/asound/cards" diff --git a/core/modules/beamergui/data/opt/openslx/scripts/beamergui-mode_setter b/core/modules/beamergui/data/opt/openslx/scripts/beamergui-mode_setter index 503e44fa..b747d257 100755 --- a/core/modules/beamergui/data/opt/openslx/scripts/beamergui-mode_setter +++ b/core/modules/beamergui/data/opt/openslx/scripts/beamergui-mode_setter @@ -55,13 +55,28 @@ if [ ${#OUTPUTNAMES[@]} -eq 2 ]; then # Either of them a projector? BEAMER= + MAYBEAMER= + SMALL= for i in 0 1; do - WIDTH=$(grep -E "^${OUTPUTNAMES[$i]}.*[0-9]+mm x [0-9]+mm" <<<"$XRANDR" | head -n 1 | grep -o -E ' [0-9]+mm x' | grep -o -E '[0-9]+') - if [ -z "$WIDTH" ] || [ "$WIDTH" -eq 0 ] || [ "$WIDTH" -gt 900 ]; then - echo "Screen $i is beamer, width is '$WIDTH'" - BEAMER=$i - fi + WIDTH=$(grep -E "^${OUTPUTNAMES[$i]}.*[0-9]+mm x [0-9]+mm" <<<"$XRANDR" | head -n 1 | grep -o -E ' [0-9]+mm x' | grep -o -E '[0-9]+') + if [ -z "$WIDTH" ] || [ "$WIDTH" -eq 0 ] || [ "$WIDTH" -gt 900 ]; then + echo "Screen $i is beamer, width is '$WIDTH'" + BEAMER=$i + elif [ -n "$WIDTH" ] && [ "$WIDTH" -gt 700 ]; then + MAYBEAMER=$i + elif [ -n "$WIDTH" ] && [ "$WIDTH" -lt 550 ]; then + SMALL=yes + fi done + if [ -z "$BEAMER" ] && [ -n "$MAYBEAMER" ] && [ -n "$SMALL" ]; then + # This is a hack on top of the other hack; we already treat outputs reporting a sufficiently large width + # as beamers, as we have encountered such devices in the wild. However, we might have just a large TV connected + # that is intended to be used just like a beamer to present the screen to the audience. So if we have a screen + # that is at least 70cm wide and the other one is no wider than 55cm we treat this as a beamer setup aswell. + # The reasoning here is that if it were a dual screen setup, the screens should be roughly the same size. + echo "Treating $MAYBEAMER as beamer as size difference is big enough" + BEAMER=$MAYBEAMER + fi if [ -n "$BEAMER" ]; then echo "${OUTPUTNAMES[$BEAMER]} is a beamer. " @@ -160,6 +175,6 @@ if [ ${#OUTPUTNAMES[@]} -eq 2 ]; then fi fi else - echo "\e[32mOther than two outputs.\e[0m" + echo -e "\e[32mOther than two outputs.\e[0m" fi diff --git a/core/modules/brazilian/module.build b/core/modules/brazilian/module.build index c6fbe0ff..a611a866 100644 --- a/core/modules/brazilian/module.build +++ b/core/modules/brazilian/module.build @@ -18,7 +18,7 @@ build() { fi # Put everything we build or get from the system in build dir - local FILELIST="$MODULE_WORK_DIR/list_copy_build" + local FILELIST="${MODULE_WORK_DIR}/list_copy_build" rm -f "$FILELIST" # Copy required directories from source system to build dir diff --git a/core/modules/busybox/module.build b/core/modules/busybox/module.build index 46b60c1c..8a7d58fb 100644 --- a/core/modules/busybox/module.build +++ b/core/modules/busybox/module.build @@ -1,4 +1,3 @@ -#!/bin/bash fetch_source() { git clone --depth 1 "${REQUIRED_GIT}" --branch "$REQUIRED_BRANCH" src || perror "Could not clone busybox git" diff --git a/core/modules/busybox/module.conf b/core/modules/busybox/module.conf index 6acfa16c..3214d95e 100644 --- a/core/modules/busybox/module.conf +++ b/core/modules/busybox/module.conf @@ -1,5 +1,5 @@ REQUIRED_GIT="git://git.busybox.net/busybox" -REQUIRED_BRANCH="1_22_1" +REQUIRED_BRANCH="1_25_1" REQUIRED_BINARIES="busybox" REQUIRED_DIRECTORIES=" /bin diff --git a/core/modules/busybox/openslx-busybox-config b/core/modules/busybox/openslx-busybox-config index 00a008d7..92a7af47 100644 --- a/core/modules/busybox/openslx-busybox-config +++ b/core/modules/busybox/openslx-busybox-config @@ -178,7 +178,9 @@ CONFIG_BASENAME=y CONFIG_CAT=y CONFIG_DATE=y CONFIG_FEATURE_DATE_ISOFMT=y -# CONFIG_FEATURE_DATE_NANO is not set +CONFIG_FEATURE_DATE_NANO=y +CONFIG_TRUNCATE=y +CONFIG_UNLINK=y CONFIG_FEATURE_DATE_COMPAT=y # CONFIG_HOSTID is not set CONFIG_ID=y @@ -207,7 +209,7 @@ CONFIG_CP=y # CONFIG_FEATURE_CP_LONG_OPTIONS is not set CONFIG_CUT=y CONFIG_DD=y -# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y # CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set # CONFIG_FEATURE_DD_IBS_OBS is not set CONFIG_DF=y @@ -384,10 +386,11 @@ CONFIG_FEATURE_VI_REGEX_SEARCH=y CONFIG_FEATURE_VI_USE_SIGNALS=y CONFIG_FEATURE_VI_DOT_CMD=y CONFIG_FEATURE_VI_READONLY=y -# CONFIG_FEATURE_VI_SETOPTS is not set +CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y CONFIG_FEATURE_VI_ASK_TERMINAL=y +CONFIG_FEATURE_VI_UNDO=y # CONFIG_FEATURE_ALLOW_EXEC is not set # diff --git a/core/modules/consolekit/module.build b/core/modules/consolekit/module.build index 6f1dd2e7..0626aae4 100644 --- a/core/modules/consolekit/module.build +++ b/core/modules/consolekit/module.build @@ -8,7 +8,7 @@ build() { COPYLIST="list_dpkg_output" [ -e "${COPYLIST}" ] && rm "${COPYLIST}" - list_packet_files >> "${COPYLIST}" + list_packet_files >> "${COPYLIST}" tarcopy "$(cat "${COPYLIST}" | sort -u)" "${MODULE_BUILD_DIR}" # Systemd/dbus mkdir -p "$MODULE_BUILD_DIR/usr/share/dbus-1/system-services" "$MODULE_BUILD_DIR/etc/systemd/system" diff --git a/core/modules/cron/data/opt/openslx/scripts/cron-sendmail b/core/modules/cron/data/opt/openslx/scripts/cron-sendmail index 3ce2a19d..f46c226d 100755 --- a/core/modules/cron/data/opt/openslx/scripts/cron-sendmail +++ b/core/modules/cron/data/opt/openslx/scripts/cron-sendmail @@ -10,16 +10,14 @@ if [ "x$SLX_CRON_MAIL" = "xslxlog" ]; then SUBJ=$(grep '^Subject: .*$' "$TMP" | cut -c 10-) if [ -n "$SUBJ" ]; then - slxlog "cron" "$SUBJ" "$TMP" + slxlog --delete "cron" "$SUBJ" "$TMP" fi - - rm -f -- "$TMP" elif [ -n "$SLX_CRON_MAIL" ] && [ -x "$SLX_CRON_MAIL" ]; then # see if SLX_CRON_MAIL is a valid binary and use that - $SLX_CRON_MAIL $@ + $SLX_CRON_MAIL "$@" elif which sendmail 2> /dev/null; then # fallback to sendmail - sendmail $@ + sendmail "$@" elif which logger 2> /dev/null; then # nothing worked, write to syslog if logger is present TMP=$(mktemp /tmp/cron.XXXXXXXX) diff --git a/core/modules/cron/module.build b/core/modules/cron/module.build index a80caf57..1f31ac21 100644 --- a/core/modules/cron/module.build +++ b/core/modules/cron/module.build @@ -1,17 +1,13 @@ -#!/bin/bash - - fetch_source() { [ -d "${MODULE_WORK_DIR}/src/.git" ] && return 0 rm -rf -- "${MODULE_WORK_DIR}/src" - git clone --depth 1 "${REQUIRED_GIT}" "${MODULE_WORK_DIR}/src" || perror "Could not create ${MODULE_WORK_DIR}/src" + git clone "${REQUIRED_GIT}" "${MODULE_WORK_DIR}/src" || perror "Could not clone git to ${MODULE_WORK_DIR}/src" cd "${MODULE_WORK_DIR}/src" git checkout "${REQUIRED_COMMIT}" || perror "Could not switch to required commit" - cd - + cd - &>/dev/null } build() { - # compilation cd "${MODULE_WORK_DIR}/src" || perror "Could not cd to '${MODULE_WORK_DIR}/src'. Did fetch_source work?" ./autogen.sh || perror "Autogen failed" @@ -22,7 +18,6 @@ build() { # NO MAKE INSTALL: Copy to build dir, since there are no shared libs linked in mkdir -p "${MODULE_BUILD_DIR}/opt/openslx/sbin" cp "${MODULE_WORK_DIR}/src/src/crond" "${MODULE_BUILD_DIR}/opt/openslx/sbin/" || perror "Could not copy crond binary to ${MODULE_BUILD_DIR}" - cd - &>/dev/null } diff --git a/core/modules/cron/module.conf b/core/modules/cron/module.conf index 60d5555d..6f07729f 100644 --- a/core/modules/cron/module.conf +++ b/core/modules/cron/module.conf @@ -1,5 +1,5 @@ REQUIRED_GIT="http://git.fedorahosted.org/git/cronie.git" -REQUIRED_COMMIT="bab45f0b817d8829f2423e033d90974c9a3abc20" +REQUIRED_COMMIT="c219d7cb9d4887f685ac4ff1e9439b0d8aa39ef6" REQUIRED_BINARIES=" crond " diff --git a/core/modules/dbus/module.build b/core/modules/dbus/module.build index c6b05a8a..71f6f783 100644 --- a/core/modules/dbus/module.build +++ b/core/modules/dbus/module.build @@ -7,10 +7,10 @@ fetch_source() { build() { COPYLIST="list_dpkg_output" [ -e "${COPYLIST}" ] && rm "${COPYLIST}" - + list_packet_files >> "${COPYLIST}" tarcopy "$(cat "${COPYLIST}" | sort -u)" "${MODULE_BUILD_DIR}" - + # Generate systemd files mkdir -p "$MODULE_BUILD_DIR/etc/systemd/system" # This is ugly, as the command line arguments changed over time. Try to do the right thing (whatever that is) diff --git a/core/modules/dbus/module.conf b/core/modules/dbus/module.conf index 5e5dc4f8..529a1b0d 100644 --- a/core/modules/dbus/module.conf +++ b/core/modules/dbus/module.conf @@ -1,4 +1,4 @@ -REQUIRED_BINARIES=" +REQUIRED_BINARIES=" dbus-cleanup-sockets dbus-daemon dbus-uuidgen @@ -6,7 +6,7 @@ REQUIRED_BINARIES=" dbus-send dbus-daemon-launch-helper dbus-launch - " +" REQUIRED_DIRECTORIES=" /etc/dbus-1 " diff --git a/core/modules/dbus/module.conf.ubuntu b/core/modules/dbus/module.conf.ubuntu index 558eea7f..3f390d20 100644 --- a/core/modules/dbus/module.conf.ubuntu +++ b/core/modules/dbus/module.conf.ubuntu @@ -1,5 +1,6 @@ REQUIRED_CONTENT_PACKAGES=" dbus + dbus-x11 " REQUIRED_FILES+=" /etc/default/dbus diff --git a/core/modules/debug-report-bwlp/data/opt/openslx/bin/debug_report b/core/modules/debug-report-bwlp/data/opt/openslx/bin/debug_report new file mode 100755 index 00000000..e0d7a9b8 --- /dev/null +++ b/core/modules/debug-report-bwlp/data/opt/openslx/bin/debug_report @@ -0,0 +1,115 @@ +#!/bin/bash +# bash because of {,} expansion + +TOOLS=" + journalctl + systemctl + loginctl + lspci + lsusb + lsmod + mount + dmesg + dmidecode +" + +URL="http://132.230.8.113/error_report.php" + +if [ "$UID" != "0" ]; then + echo "Debug Reports können nur von root versendet werden" >&2 + exit 1 +fi + +if ! curl -H "Expect:" -f -s -S --connect-timeout 5 "$URL" > /dev/null; then + echo "Kann den Debug-Report-Server in Freiburg nicht erreichen. :-(" >&2 + exit 1 +fi + +rm -rf /tmp/debug-report +mkdir -p /tmp/debug-report/{static,generated} + +if [ ! -d /tmp/debug-report ]; then + echo "FEHLER: Konnte /tmp/debug-report nicht erstellen!" >&2 + exit 1 +fi + +if ! cd /tmp/debug-report; then + echo "Cannot go to /tmp/debug-report" + exit 1 +fi + +cat > err-desc <<HEREEND + +# Bitte hier kurz eine passende Fehlerbeschreibung eingeben, anschließend +# Strg+O, ENTER, Strg+X, ENTER drücken. +HEREEND + +nano -w err-desc + +if ! grep -vqE '(^$)|(^# )' err-desc; then + echo "Fehlerberichterstattung aufgrund leerer Beschreibung abgebrochen." + exit 1 +fi + +echo -n "Beginne mit dem Erstellen des Fehlerberichts..." + +. /opt/openslx/config + +echo "TIME INFORMATION (hwclock, date):" > metadata +hwclock >> metadata +date >> metadata +for srv in $SLX_NTP_SERVER 0.de.pool.ntp.org; do + ntpdate -u -q -p 2 -t 1 "$srv" >> metadata 2> /dev/null && break +done +echo -n "..." + +cp /opt/openslx/config /tmp/udhcpclog static/ 2> /dev/null +echo -n "." + +FILES=$(find /tmp/vmware* /tmp/virt /tmp/vmchooser* -type f \( -name "*.log" -o -name "*.conf" -o -name "*.xml" \) 2> /dev/null) +if [ -n "$FILES" ]; then + tar ckf static/vm-related.tar $FILES +fi + +echo -n "." + +cp /var/log/Xorg.0.lo* static/ 2> /dev/null +cp /var/log/{auth.log,kdm.log,syslog,messages,user.log} static/ 2> /dev/null +cp /proc/{cpu,mem}info static/ 2> /dev/null +echo -n "." + +for tool in $TOOLS; do + $tool > "generated/${tool}-out" 2> "generated/${tool}-err" + echo -n "." +done + +ip a > "generated/ip-a-out" 2> "generated/ip-a-err" +echo -n "." + +systemctl status > "generated/systemctl-status-out" 2> "generated/systemctl-status-err" +echo -n "." + +ps auxf > "generated/ps-out" 2> "generated/ps-err" +echo -n "." + +find generated/ -type f -name "*-err" -size 0 -delete > /dev/null 2>/dev/null + +echo "..fertig!" + +cd /tmp +rm -f -- error-report.tar.gz +echo -n "Packe Fehlerbericht ein..." +if ! tar czf error-report.tar.gz debug-report; then + echo "Fehler beim Packen des Berichts!" >&2 + exit 1 +fi +echo "....fertig!" + +echo -n "Lade Fehlerbericht hoch...." +if ! curl -H "Expect:" -f -s -S -F "file=@error-report.tar.gz;filename=report" "$URL" > /dev/null; then + echo "Fehler beim Hochladen des Fehlerberichts :-(" >&2 + exit 1 +fi + +echo "Fehlerbericht erfolgreich versendet!" + diff --git a/core/modules/debug-report-bwlp/module.build b/core/modules/debug-report-bwlp/module.build new file mode 100644 index 00000000..1be608b8 --- /dev/null +++ b/core/modules/debug-report-bwlp/module.build @@ -0,0 +1,23 @@ +fetch_source() { + : +} + +build() { + + for BIN in $REQUIRED_BINARIES; do + OPT="${BIN:0:1}" + [[ "$BIN" == @* ]] && BIN=$(echo "$BIN" | cut -c 2-) + BIN_LOCATION=$(which ${BIN}) + if [ ! -z ${BIN_LOCATION} -a -e ${BIN_LOCATION} ]; then + tarcopy "$(get_link_chain ${BIN_LOCATION})" "${MODULE_BUILD_DIR}" + elif [ "$OPT" != "@" ]; then + perror "'${BIN}' not found on system." + else + pwarning "'${BIN}' not found on the system." + fi + done +} + +post_copy() { + : +} diff --git a/core/modules/debug-report-bwlp/module.conf b/core/modules/debug-report-bwlp/module.conf new file mode 100644 index 00000000..45830ef8 --- /dev/null +++ b/core/modules/debug-report-bwlp/module.conf @@ -0,0 +1,4 @@ +REQUIRED_BINARIES=" + curl + nano +" diff --git a/core/modules/debug-report-bwlp/module.conf.debian b/core/modules/debug-report-bwlp/module.conf.debian new file mode 100644 index 00000000..14ae2d29 --- /dev/null +++ b/core/modules/debug-report-bwlp/module.conf.debian @@ -0,0 +1,4 @@ +REQUIRED_INSTALLED_PACKAGES=" + curl + nano +" diff --git a/core/modules/debug-report-bwlp/module.conf.opensuse b/core/modules/debug-report-bwlp/module.conf.opensuse new file mode 100644 index 00000000..14ae2d29 --- /dev/null +++ b/core/modules/debug-report-bwlp/module.conf.opensuse @@ -0,0 +1,4 @@ +REQUIRED_INSTALLED_PACKAGES=" + curl + nano +" diff --git a/core/modules/debug-report-bwlp/module.conf.ubuntu b/core/modules/debug-report-bwlp/module.conf.ubuntu new file mode 100644 index 00000000..14ae2d29 --- /dev/null +++ b/core/modules/debug-report-bwlp/module.conf.ubuntu @@ -0,0 +1,4 @@ +REQUIRED_INSTALLED_PACKAGES=" + curl + nano +" diff --git a/core/modules/debug/data/opt/openslx/bin/debug_report b/core/modules/debug/data/opt/openslx/bin/debug_report index 4cdfae4e..40f0c310 100755 --- a/core/modules/debug/data/opt/openslx/bin/debug_report +++ b/core/modules/debug/data/opt/openslx/bin/debug_report @@ -1,4 +1,5 @@ -#!/bin/ash +#!/bin/bash +# bash because of {,} expansion TOOLS=" journalctl @@ -8,6 +9,7 @@ TOOLS=" lsusb lsmod mount + dmidecode " URL="http://132.230.8.113/error_report.php" @@ -30,37 +32,49 @@ if [ ! -d /tmp/debug-report ]; then exit 1 fi -cd /tmp/debug-report +if ! cd /tmp/debug-report; then + echo "Cannot go to /tmp/debug-report" + exit 1 +fi cat > err-desc <<HEREEND # Bitte hier kurz eine passende Fehlerbeschreibung eingeben, anschließend -# Strg+O, ENTER, und Strg+X drücken. +# Strg+O, ENTER, Strg+X, ENTER drücken. HEREEND nano -w err-desc +if ! grep -vqE '(^$)|(^# )' err-desc; then + echo "Fehlerberichterstattung aufgrund leerer Beschreibung abgebrochen." + exit 1 +fi + echo -n "Beginne mit dem Erstellen des Fehlerberichts..." . /opt/openslx/config -echo "TIME INFORMATION:" > metadata +echo "TIME INFORMATION (hwclock, date):" > metadata hwclock >> metadata date >> metadata -for srv in 132.230.1.9 $SLX_NTP_SERVER 0.de.pool.ntp.org; do - ntpdate -u -q -p 2 -t 1 "$srv" >> metadata && break +for srv in $SLX_NTP_SERVER 0.de.pool.ntp.org; do + ntpdate -u -q -p 2 -t 1 "$srv" >> metadata 2> /dev/null && break done echo -n "..." cp /opt/openslx/config /tmp/udhcpclog static/ 2> /dev/null echo -n "." -find /tmp/vmware* -name "*.log" -exec cp {} static/ \; 2> /dev/null +FILES=$(find /tmp/vmware* /tmp/virt /tmp/vmchooser* -type f \( -name "*.log" -o -name "*.conf" -o -name "*.xml" \) 2> /dev/null) +if [ -n "$FILES" ]; then + tar ckf static/vm-related.tar $FILES +fi + echo -n "." cp /var/log/Xorg.0.lo* static/ 2> /dev/null cp /var/log/{auth.log,kdm.log,syslog,messages,user.log} static/ 2> /dev/null -cp /proc/cpuinfo static/ 2> /dev/null +cp /proc/{cpu,mem}info static/ 2> /dev/null echo -n "." for tool in $TOOLS; do @@ -74,13 +88,15 @@ echo -n "." systemctl status > "generated/systemctl-status-out" 2> "generated/systemctl-status-err" echo -n "." -ps aux > "generated/ps-out" 2> "generated/ps-err" +ps auxf > "generated/ps-out" 2> "generated/ps-err" echo -n "." +find generated/ -type f -name "*-err" -size 0 -delete > /dev/null 2>/dev/null + echo "..fertig!" cd /tmp -rm -f error-report.tar.gz +rm -f -- error-report.tar.gz echo -n "Packe Fehlerbericht ein..." if ! tar czf error-report.tar.gz debug-report; then echo "Fehler beim Packen des Berichts!" >&2 diff --git a/core/modules/dhcpc-busybox/data/opt/openslx/scripts/systemd-udhcpc++ b/core/modules/dhcpc-busybox/data/opt/openslx/scripts/systemd-udhcpc++ index b3de09e7..76c4fe95 100755 --- a/core/modules/dhcpc-busybox/data/opt/openslx/scripts/systemd-udhcpc++ +++ b/core/modules/dhcpc-busybox/data/opt/openslx/scripts/systemd-udhcpc++ @@ -1,5 +1,4 @@ #!/bin/bash -PATH=$PATH:/opt/openslx/bin:/opt/openslx/sbin NET_IF="$1" NET_IP="$(ip addr show dev "${NET_IF}" | grep -m1 '^\s*inet ' | awk -F " " '{print $2}' | awk -F "/" '{print $1}')" diff --git a/core/modules/dhcpc-busybox/data/opt/openslx/scripts/udhcpc-openslx b/core/modules/dhcpc-busybox/data/opt/openslx/scripts/udhcpc-openslx index dd8cd8ba..776f3f3b 100755 --- a/core/modules/dhcpc-busybox/data/opt/openslx/scripts/udhcpc-openslx +++ b/core/modules/dhcpc-busybox/data/opt/openslx/scripts/udhcpc-openslx @@ -87,16 +87,29 @@ case "$1" in # Update resolver configuration file CONF="" + # Own domain suffix if [ -n "$domain" ]; then - printf -v CONF "${CONF}domain $domain\n" + : elif [ -n "$dns_fqdn" ]; then domain="${dns_fqdn#*.}" - printf -v CONF "${CONF}domain $domain\n" elif [ -n "$SLX_NET_DOMAIN" ]; then domain="$SLX_NET_DOMAIN" - printf -v CONF "${CONF}domain $domain\n" fi + if [ -n "$domain" ]; then + printf -v CONF "${CONF}domain ${domain%% *}\n" + fi + # Add domain to list of search domains if not in there yet + if [ -n "$domain" ] && [ -n "$search" ]; then + FOUND=no + for sd in $search; do + [ "x$sd" = "x$domain" ] && FOUND=yes + done + [ "$FOUND" = "no" ] && search="$domain $search" + elif [ -n "$domain" ]; then + search="$domain" + fi + # Search domains if [ -n "$search" ]; then printf -v CONF "${CONF}search $search\n" elif [ -n "$SLX_SEARCH_DOMAIN" ]; then @@ -125,6 +138,15 @@ case "$1" in if [ "$interface" == "br0" ]; then # Update IP sed -i "s/^\(SLX_PXE_CLIENT_IP=\).*$/\1'$ip'/" /opt/openslx/config + # Write DOMAIN and SEARCH to /opt/openslx/config if empty + if [ -z "$SLX_NET_DOMAIN" ] && [ -n "$domain" ]; then + sed -i "/^SLX_NET_DOMAIN=/d" /opt/openslx/config + echo "SLX_NET_DOMAIN='$domain'" >> /opt/openslx/config + fi + if [ -z "$SLX_NET_SEARCH" ] && [ -n "$search" ]; then + sed -i "/^SLX_NET_SEARCH=/d" /opt/openslx/config + echo "SLX_NET_SEARCH='$search'" >> /opt/openslx/config + fi # Only if network is not ready yet if [ ! -e "/run/network/network-ready" ]; then @@ -150,16 +172,6 @@ case "$1" in fi fi - # if domain is given from dhcp, save it to openslx config for later use in VMs - if [ -n "$domain" ]; then - # check if SLX_NET_DOMAIN is in the config at all - if grep '^SLX_NET_DOMAIN=' /opt/openslx/config 2>/dev/null; then - sed -i "s/^\(SLX_NET_DOMAIN=\).*$/\1'$domain'/" /opt/openslx/config - else - # not set, add it - echo "SLX_NET_DOMAIN='$domain'" >> /opt/openslx/config - fi - fi # Update /etc/issue for proper spacing /opt/openslx/scripts/openslx-create_issue touch "/run/network/network-ready" @@ -200,9 +212,6 @@ case "$1" in # "default route exists" target if [ -n "$router" ] && [ ! -e "/run/network/gateway-ready" ]; then touch "/run/network/gateway-ready" - # Write to openslx-config - echo "# Config written by openslx-dhcp-script (3)" >> /opt/openslx/config - echo "SLX_DNS='$dns'" >> /opt/openslx/config systemctl start network-gateway.target & fi diff --git a/core/modules/dmidecode/module.build b/core/modules/dmidecode/module.build new file mode 100644 index 00000000..f37536af --- /dev/null +++ b/core/modules/dmidecode/module.build @@ -0,0 +1,27 @@ +#!/bin/bash + + +fetch_source() { + [ -d "${MODULE_WORK_DIR}/src/.git" ] && return 0 + rm -rf -- "${MODULE_WORK_DIR}/src" + git clone "${REQUIRED_GIT}" "${MODULE_WORK_DIR}/src" || perror "Could not create ${MODULE_WORK_DIR}/src" +} + +build() { + + # compilation + cd "${MODULE_WORK_DIR}/src" || perror "Could not cd to '${MODULE_WORK_DIR}/src'. Did fetch_source work?" + + make || perror "Could not compile dmidecode using 'make'." + + # NO MAKE INSTALL: Copy to build dir, since there are no shared libs linked in + mkdir -p "${MODULE_BUILD_DIR}/usr/sbin" + cp "${MODULE_WORK_DIR}/src/dmidecode" "${MODULE_BUILD_DIR}/usr/sbin/" || perror "Could not copy dmidecode binary to ${MODULE_BUILD_DIR}" + + cd - &>/dev/null +} + +post_copy() { + : +} + diff --git a/core/modules/dmidecode/module.conf b/core/modules/dmidecode/module.conf new file mode 100644 index 00000000..3f58cff4 --- /dev/null +++ b/core/modules/dmidecode/module.conf @@ -0,0 +1,4 @@ +REQUIRED_GIT="git://git.savannah.nongnu.org/dmidecode.git" +REQUIRED_BINARIES=" + dmidecode +" diff --git a/core/modules/dnbd3/data/opt/openslx/scripts/systemd-setup_dnbd3 b/core/modules/dnbd3/data/opt/openslx/scripts/systemd-setup_dnbd3 index e519b1b8..8c2a6485 100755 --- a/core/modules/dnbd3/data/opt/openslx/scripts/systemd-setup_dnbd3 +++ b/core/modules/dnbd3/data/opt/openslx/scripts/systemd-setup_dnbd3 @@ -10,7 +10,7 @@ for i in /dev/dnbd*; do echo 8192 > "/sys/block/dnbd${i#/dev/dnbd}/queue/nr_requests" done -exec /opt/openslx/bin/dnbd3-client --daemon +exec dnbd3-client --daemon slxlog "dnbd3-daemon" "Error launching dnbd3-client daemon" exit 1 diff --git a/core/modules/dnbd3/module.build b/core/modules/dnbd3/module.build index e7c91f45..bc07a7ca 100644 --- a/core/modules/dnbd3/module.build +++ b/core/modules/dnbd3/module.build @@ -27,19 +27,28 @@ build() { cd "$MODULE_WORK_DIR/src/kmod" || perror "Could not CD to standalone dnbd3 kmod dir" make MODULE_NAME=dnbd3 KDIR="$KERNEL_HEADERS_DIR" || perror "Could not compile kernel module" mkdir -p "$MODULE_BUILD_DIR/lib/modules/dnbd3" || perror "Could not create lib/modules/dnbd3" - mkdir -p "$MODULE_BUILD_DIR/opt/openslx/bin" || perror "Coould not create opt/openslx/bin" - cp "$MODULE_WORK_DIR/src/kmod/dnbd3.ko" "$MODULE_BUILD_DIR/lib/modules/dnbd3/" || perror "could not cp dnbd3.ko" + mkdir -p "$MODULE_BUILD_DIR/opt/openslx/bin" || perror "Could not create opt/openslx/bin" + cp "$MODULE_WORK_DIR/src/kmod/dnbd3.ko" "$MODULE_BUILD_DIR/lib/modules/dnbd3/" || perror "Could not copy dnbd3.ko" cd "$MODULE_BUILD_DIR/opt/openslx/bin" || perror "Could not cd to build dir for client binary" - cmake "$MODULE_WORK_DIR/src/dnbd3" || perror "Could not cmake" + cmake \ + -DBUILD_FUSE_CLIENT=ON \ + -DBUILD_KERNEL_MODULE=ON \ + -DBUILD_SERVER=OFF \ + -DBUILD_STRESSTEST=OFF \ + "$MODULE_WORK_DIR/src/dnbd3" || perror "Could not cmake" make dnbd3-client || perror "Could not make dnbd3-client" make dnbd3-fuse || perror "Could not make dnbd3-fuse" chown root:root "dnbd3-client" "dnbd3-fuse" chmod +xs "dnbd3-client" chmod +x "dnbd3-fuse" cd "$MODULE_WORK_DIR" + + COPYLIST="list_dpkg_output" + [ -e "$COPYLIST" ] && rm "$COPYLIST" + list_packet_files >> "$COPYLIST" + tarcopy "$(cat "$COPYLIST" | sort -u)" "${MODULE_BUILD_DIR}" } post_copy() { : } - diff --git a/core/modules/dnbd3/module.conf b/core/modules/dnbd3/module.conf index 29442db7..fba4a88b 100644 --- a/core/modules/dnbd3/module.conf +++ b/core/modules/dnbd3/module.conf @@ -1,9 +1,10 @@ REQUIRED_MODULES="kernel" REQUIRED_GIT="git://git.openslx.org/dnbd3.git" -REQUIRED_COMMIT="6d6455b271ac99c5862691620e1217ed7b3b78b4" +REQUIRED_COMMIT="0df5be95c5073dfe03234abd26c9b60340f48bdf" REQUIRED_BINARIES=" dnbd3-client dnbd3-fuse + fusermount " REQUIRED_DIRECTORIES=" /lib/modules diff --git a/core/modules/dnbd3/module.conf.ubuntu b/core/modules/dnbd3/module.conf.ubuntu index 8033437b..69b5b9de 100644 --- a/core/modules/dnbd3/module.conf.ubuntu +++ b/core/modules/dnbd3/module.conf.ubuntu @@ -1,9 +1,11 @@ REQUIRED_CONTENT_PACKAGES=" cmake + fuse " REQUIRED_INSTALLED_PACKAGES=" cmake zlib1g-dev libfuse-dev + fuse " diff --git a/core/modules/dunst/data/etc/xdg/dunst/dunstrc b/core/modules/dunst/data/etc/xdg/dunst/dunstrc new file mode 100644 index 00000000..a9f661cb --- /dev/null +++ b/core/modules/dunst/data/etc/xdg/dunst/dunstrc @@ -0,0 +1,56 @@ +[global] + font = DejaVu-Sans 10 + allow_markup = yes + plain_text = no + format = " <b>%s</b>\n%b" + sort = yes + indicate_hidden = yes + alignment = left + bounce_freq = 0 + show_age_threshold = 60 + word_wrap = yes + ignore_newline = no + geometry = "320x5-30+20" + shrink = no + transparency = 0 + idle_threshold = 120 + monitor = 0 + follow = mouse + sticky_history = yes + history_length = 20 + show_indicators = yes + line_height = 0 + notification_height = 0 + separator_height = 2 + padding = 8 + horizontal_padding = 8 + separator_color = frame + startup_notification = false + icon_position = left + icon_folders = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ + +[frame] + width = 2 + color = "#bbbbbb" + +[shortcuts] + close = ctrl+mod1+mod4+space + close_all = ctrl+mod1+mod4+shift+space + history = ctrl+mod1+mod4+grave + context = ctrl+mod1+mod4+shift+period + +[urgency_low] + background = "#222222" + foreground = "#dddddd" + timeout = 15 + +[urgency_normal] + background = "#184567" + foreground = "#ffffff" + timeout = 15 + +[urgency_critical] + background = "#c00000" + foreground = "#ffff00" + timeout = 0 + diff --git a/core/modules/dunst/module.build b/core/modules/dunst/module.build new file mode 100644 index 00000000..16e0bb5b --- /dev/null +++ b/core/modules/dunst/module.build @@ -0,0 +1,22 @@ +#!/bin/bash + +fetch_source() { + : +} + +build() { + COPYLIST="list_dpkg_output" + [ -e "$COPYLIST" ] && rm "$COPYLIST" + + list_packet_files >> "$COPYLIST" + tarcopy "$(cat "$COPYLIST" | sort -u)" "${MODULE_BUILD_DIR}" + + # copy udev rules to correct location + [ -d "${MODULE_BUILD_DIR}/lib/udev" ] && mv "${MODULE_BUILD_DIR}/lib/udev" "${MODULE_BUILD_DIR}/usr/lib/" +} + +post_copy() { + mkdir -p "${TARGET_BUILD_DIR}/etc/X11" + [ ! -e ${TARGET_BUILD_DIR}/etc/X11/X ] && ln -s /usr/bin/Xorg ${TARGET_BUILD_DIR}/etc/X11/X +} + diff --git a/core/modules/dunst/module.conf b/core/modules/dunst/module.conf new file mode 100644 index 00000000..bf5386db --- /dev/null +++ b/core/modules/dunst/module.conf @@ -0,0 +1,10 @@ +REQUIRED_BINARIES=" + dunst + notify-send +" +REQUIRED_DIRECTORIES=" + /usr/share/dbus-1 +" +REQUIRED_FILES=" +" + diff --git a/core/modules/dunst/module.conf.ubuntu b/core/modules/dunst/module.conf.ubuntu new file mode 100644 index 00000000..ffbc9295 --- /dev/null +++ b/core/modules/dunst/module.conf.ubuntu @@ -0,0 +1,9 @@ +REQUIRED_INSTALLED_PACKAGES=" + dunst + libnotify-bin +" +REQUIRED_CONTENT_PACKAGES=" + dunst + libnotify-bin +" +REQUIRED_FILES="" diff --git a/core/modules/gdisk/module.conf.ubuntu b/core/modules/gdisk/module.conf.ubuntu new file mode 100644 index 00000000..78fcd634 --- /dev/null +++ b/core/modules/gdisk/module.conf.ubuntu @@ -0,0 +1,5 @@ +REQUIRED_CONTENT_PACKAGES=" + gdisk + xfsprogs + e2fsprogs +" diff --git a/core/modules/hardware-stats/data/etc/systemd/system/hardware-stats.service b/core/modules/hardware-stats/data/etc/systemd/system/hardware-stats.service index c28e75a5..ca31c695 100644 --- a/core/modules/hardware-stats/data/etc/systemd/system/hardware-stats.service +++ b/core/modules/hardware-stats/data/etc/systemd/system/hardware-stats.service @@ -1,7 +1,7 @@ [Unit] Description=Gather statistics about this machine and send to boot server DefaultDependencies=no -After=tmp.target multi-user.target +After=tmp.target Wants=tmp.target [Service] diff --git a/core/modules/hardware-stats/data/opt/openslx/scripts/cron-system_usage_update b/core/modules/hardware-stats/data/opt/openslx/scripts/cron-system_usage_update index 232e5eab..df8dab45 100755 --- a/core/modules/hardware-stats/data/opt/openslx/scripts/cron-system_usage_update +++ b/core/modules/hardware-stats/data/opt/openslx/scripts/cron-system_usage_update @@ -10,16 +10,76 @@ UUID=$(cat "/run/system-uuid") [ -z "$UUID" ] && exit 1 USED=0 +Name= for SESSION in $(loginctl | awk '{print $1}'); do unset Display Remote State - eval $(loginctl -p Display -p Remote -p State -p Class show-session "$SESSION") - if [ -n "$Display" ] && [ "$Remote" = "no" ] && [ "$State" = "active" ] && [ "$Class" = "user" ]; then - USED=1 - break; + eval $(loginctl -p Display -p Remote -p State -p Class -p Name show-session "$SESSION") + if [ "$Display" = ":0" ] && [ "$Remote" = "no" ] && [ "$State" = "active" -o "$State" = "online" ] && [ "$Class" = "user" ]; then + USED=1 # We only consider sessions on the primary display, which should always be the case + break fi done +# Also report usage of /tmp and swap +TMP=$(df -P /tmp | grep -m1 ' /tmp$') +TMP_SIZE=$(echo $TMP | awk '{print $2}') +TMP_FREE=$(echo $TMP | awk '{print $4}') +SWAP_FREE=$(grep -m1 ^SwapFree: /proc/meminfo | awk '{print $2}') + curl -s --data-urlencode "type=~runstate" --data-urlencode "uuid=$UUID" --data-urlencode "used=$USED" \ - "$SLX_REMOTE_LOG" > /dev/null 2>&1 + --data-urlencode "user=$Name" --data-urlencode "tmpsize=$TMP_SIZE" --data-urlencode "tmpfree=$TMP_FREE" \ + --data-urlencode "swapfree=$SWAP_FREE" "$SLX_REMOTE_LOG" > /dev/null 2>&1 + +# Warn user if tmp or swap usage is high; system might crash soon +WARN= +if [ "$SWAP_FREE" -gt 0 ] && [ "$SWAP_FREE" -lt 500000 ]; then # less than 500MB swap + WARN="$WARN +Der Arbeitsspeicher des Computers ist fast voll. +The computer is running out of RAM." +fi +if [ -n "$TMP_FREE" ] && [ "$TMP_FREE" -lt 500000 ]; then + WARN="$WARN +Es verbleibt wenig temporärer Speicher für die Arbeitsdaten der laufenden VM. +Little temporary storage is left for the current VM." +fi + +if [ -n "$WARN" ]; then + WARN="$WARN + +Bitte sichern Sie Ihre Arbeit und starten Sie den PC neu. +Please save your work and reboot this machine. + +Sie können einen bwLehrpool-Admin bitten, eine größere ID-44-Partition einzurichten. +You could ask a bwLehrpool administrator to create a larger ID-44 partition." + for d in $(who | awk '{print $2}' | sort -u); do + if [ "${d:0:1}" = ":" ]; then + # X11 + export DISPLAY=$d + export XAUTHORITY=$(ps a | grep " $DISPLAY " | grep -o -- '-auth.*$' | grep -m1 -v grep | awk '{print $2}') + notify-send -u critical "System instabil" "$WARN" + unset DISPLAY XAUTHORITY + elif [ "${d:0:3}" = "tty" ]; then + # Regular tty + cat > "/dev/$d" <<EOF + * + *************************** + $WARN + *************************** + * +EOF + elif [ "${d:0:3}" = "pts" ]; then + # pts - xterm or ssh session + cat > "/dev/pts/${d:3}" <<EOF + * + *************************** + $WARN + *************************** + * +EOF + fi + done +fi + +exit 0 diff --git a/core/modules/hardware-stats/data/opt/openslx/scripts/systemd-hardware_stats b/core/modules/hardware-stats/data/opt/openslx/scripts/systemd-hardware_stats index ce910a2b..cc5165dc 100755 --- a/core/modules/hardware-stats/data/opt/openslx/scripts/systemd-hardware_stats +++ b/core/modules/hardware-stats/data/opt/openslx/scripts/systemd-hardware_stats @@ -8,6 +8,31 @@ export LANG=C export LC_ALL=C +mktemp() { + /bin/mktemp && return 0 + /opt/openslx/bin/mktemp && return 0 + local FN DIR + for DIR in "tmp" "tmp" "tmp" "run/user/$UID" "run"; do + FN="/${DIR}/${RANDOM}-${$}-${UID}-$(date +%N)" + [ -e "$FN" ] && continue + touch "$FN" || continue + chmod 0600 "$FN" || continue + echo "$FN" + return 0 + done +} + +fdisk() { + local binary RET + for binary in "/opt/openslx/sbin/fdisk" "busybox fdisk" "fdisk"; do + $binary "$@" + RET=$? + [ "$RET" = "127" ] && continue # command not found + return $RET + done + return 127 +} + if [ -z "$SLX_REMOTE_LOG" ]; then echo "No remote log url given, will not report" exit 1 @@ -25,10 +50,8 @@ if [ "${#BOOTIF}" -ne "20" ]; then fi MAC=${BOOTIF:3} -which dmidecode || sleep 5 - # 2) Get machine UUID, with fallback to MAC address if it fails for some reason -UUID=$(dmidecode -s system-uuid) +UUID=$(dmidecode -q -s system-uuid | grep -v '^#' | head -n 1) if [ "${#UUID}" -ne "36" ]; then echo "Determined UUID (${UUID}) has not expected length of 36, falling back to MAC..." UUID="000000000000000-$BOOTIF" @@ -37,7 +60,10 @@ fi # 3) Uptime in seconds UPTIME=$(grep -o -E '^[0-9]+' /proc/uptime) -# 4) Number of real CPU cores +# 4) Number of real and virtual CPU cores +# Virtual, cheap way +VCORES=$(grep '^processor\s' /proc/cpuinfo | sort -u | wc -l) +# Real cores CPUCORES=$(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | sort -u | wc -l) # Fallback 1... if [ -z "$CPUCORES" ] || [ "$CPUCORES" = "0" ]; then @@ -54,7 +80,7 @@ fi CPUMODEL=$(grep -m1 '^model name\s*:' /proc/cpuinfo | sed 's/^model name\s*:\s*//;s/\s\s*/ /g;s/^ //;s/ $//') # 6) RAM -RAM=$(grep '^MemTotal:' /proc/meminfo | awk '{print $2}') +RAM=$(grep -m1 '^MemTotal:' /proc/meminfo | awk '{print $2}') RAM=$(( $RAM / 1024 )) if [ -z "$RAM" ] || [ "$RAM" -lt 500 ]; then # Fallback to dmidecode @@ -92,20 +118,32 @@ fi # 8) ID44 partition size ID44=0 -for c in $(fdisk -l | grep -E '[0-9]+[\-\+]?\s+44\s+' | awk '{print $1}'); do - val=$(blockdev --getsize64 "$c") - [ -z "$val" ] && continue - [ "$val" -gt "$ID44" ] && ID44=$val -done -ID44=$(( $ID44 / 1058576 )) # we'd rather underreport +# Try df first, make sure device starts with /dev +read -r df_dev df_size df_used df_avail df_usepercent df_mountpoint df_crap < <(df /tmp | grep ' /tmp$') +if [ -n "${df_size}" ] && [ "${df_dev:0:5}" = "/dev/" ]; then + # df reports kbytes, convert to MB + ID44=$(( df_size / 1024 )) +fi +if [ "$ID44" = 0 ]; then + # fdisk fallback + for c in $(fdisk -l | grep -E '[0-9]+[\-\+]?\s+44\s+' | awk '{print $1}'); do + val=$(blockdev --getsize64 "$c") + [ -z "$val" ] && continue + [ "$val" -gt "$ID44" ] && ID44=$val + done + # blockdev reports bytes, convert to MB + ID44=$(( $ID44 / 1058576 )) # we'd rather underreport +fi # 9) check smart values +FDISK=$(mktemp) +fdisk -l > "$FDISK" BADSECTORS=0 if which smartctl; then ALLSMART=$(mktemp) FILE=$(mktemp) [ -z "$FILE" ] && FILE="/tmp/smartctl.$$.$RANDOM.$RANDOM" - for dev in $(fdisk -l | grep -o '^Disk /dev/\S*:' | cut -c 6-); do + for dev in $(cat "$FDISK" | grep -o '^Disk /dev/\S*:' | cut -c 6-); do dev=${dev:0:-1} smartctl -i -H -A -f "brief" "$dev" > "$FILE" || continue echo "NEXTHDD=$dev" >> "$ALLSMART" @@ -129,37 +167,38 @@ fi # A) Read system model and manufacturer dmidec() { - local MODEL=$(dmidecode "$@" | sed 's/\s\s*/ /g;s/^ //;s/ $//') - case "$MODEL" in + local RETVAL=$(dmidecode "$@" 2>/dev/null | grep -v '^#' | grep -v '^Invalid' | sed 's/\s\s*/ /g;s/^ //;s/ $//') + case "$RETVAL" in ""|*"Product Name"*|*"be filled"*|"unknown"|*"product name"*) - MODEL="Unknown" + RETVAL="Unknown" ;; esac - echo "$MODEL" + echo "$RETVAL" } -MODEL=$(dmidec -s system-product-name) -MANUF=$(dmidec -s system-manufacturer) + +HW_MODEL=$(dmidec -q -s system-product-name) +HW_MANUF=$(dmidec -q -s system-manufacturer) # Try fallback to baseboard -if [ "$MODEL" = "Unknown" ]; then - MODEL=$(dmidec -s baseboard-product-name) - MANUF=$(dmidec -s baseboard-manufacturer) +if [ "$HW_MODEL" = "Unknown" ]; then + HW_MODEL=$(dmidec -q -s baseboard-product-name) + HW_MANUF=$(dmidec -q -s baseboard-manufacturer) fi -if [ "$MANUF" != "Unknown" ]; then - MODEL="$MODEL ($MANUF)" +MODEL="$HW_MODEL" +if [ "$HW_MANUF" != "Unknown" ]; then + MODEL="$MODEL ($HW_MANUF)" fi # n) Dump raw data to a file DATAFILE=$(mktemp) -[ -z "$DATAFILE" ] && DATAFILE="/root/power-stats.$$" cat > "$DATAFILE" <<-EOF ############################### CPU ##################################### Sockets: $(grep '^physical id' /proc/cpuinfo | sort -u | wc -l) Real cores: $CPUCORES -Virtual cores: $(grep '^processor' /proc/cpuinfo | sort -u | wc -l) +Virtual cores: $VCORES ######################## Partition tables ############################### EOF -fdisk -l >> "$DATAFILE" +cat "$FDISK" >> "$DATAFILE" cat >> "$DATAFILE" <<-EOF ############################ PCI ID ##################################### EOF @@ -180,6 +219,27 @@ EOF [ -n "$ALLSMART" ] && rm -f -- "$ALLSMART" +# Put some info in local file for later use +HDDCOUNT=0 +for size in $(cat "$FDISK" | grep -E '^Disk /dev.*[0-9]{11,} bytes' | grep -o -E '[0-9]{11,}'); do + [ "$size" -gt 50000000000 ] && HDDCOUNT=$(( HDDCOUNT + 1 )) +done +bashesc () { + sed s/\'/\'\"\'\"\'/g <<<$* +} +HW_MANUF=$(bashesc "$HW_MANUF") +HW_MODEL=$(bashesc "$HW_MODEL") +cat > "/run/hwinfo" <<HORST +HW_KVM='${VT}' +HW_ID44='${ID44}' +HW_MBRAM='${RAM}' +HW_HDDCOUNT='${HDDCOUNT}' +HW_MANUF='${HW_MANUF}' +HW_MODEL='${HW_MODEL}' +HW_CORES='${CPUCORES}' +HW_THREADS='${VCORES}' +HORST + # Fire away for DELAY in 1 1 0; do if curl --data-urlencode "type=~poweron" --data-urlencode "uuid=$UUID" --data-urlencode "macaddr=$MAC" \ diff --git a/core/modules/hardware-stats/module.conf b/core/modules/hardware-stats/module.conf index 5850b267..8e371d5b 100644 --- a/core/modules/hardware-stats/module.conf +++ b/core/modules/hardware-stats/module.conf @@ -1,6 +1,8 @@ +REQUIRED_MODULES=" + dmidecode +" REQUIRED_BINARIES=" rdmsr - dmidecode blockdev " diff --git a/core/modules/kdm-theme-bwlp/data/etc/kde4/kdm/kdmrc b/core/modules/kdm-theme-bwlp/data/etc/kde4/kdm/kdmrc new file mode 100644 index 00000000..3690c3c6 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/etc/kde4/kdm/kdmrc @@ -0,0 +1,55 @@ +[General] +PidFile=/var/run/kdm.pid +ServerVTs=-7 +# Always spawn :0 (this is the default but it won't hurt) +StaticServers=:0 +GreeterUID=kdm + +[X-*-Greeter] +UseTheme=true +Theme=/usr/share/desktop/themes/kdm/bwlehrpool +UseBackground=false +GreetString=bwLehrpool Workstation (%h) +SelectedUsers= +UserList=false +AuthComplain=true +AntiAliasing=true + +[X-:*-Greeter] +AllowClose=false +UseAdminSession=true + +[X-:0-Greeter] +LogSource=/dev/xconsole +PreselectUser=None +UseAdminSession=false + +[X-*-Core] +AllowRootLogin=true +AllowShutdown=All +AutoLoginEnable=false +AutoLoginAgain=true +AutoLoginDelay=5 +ServerAttempts=2 +# Custom directory so kdm never sees any other sessions - it's up to the vmchooser to list them +SessionsDirs=/opt/openslx/xsessions +TerminateServer=true + +# Session is executed to start the user's session (as the user) +# "One of the keywords failsafe, default or custom, or a string to eval by a Bourne-compatible shell is passed as the first argument." +Session=/etc/X11/Xsession +# Reset is run after a session terminates (as root) +Reset=/etc/X11/Xreset +# Setup is executed once before the greeter starts (as root) +Setup=/etc/X11/Xsetup +# Startup is executed on successful authentication, before the session is opened (as root) +Startup=/etc/X11/Xstartup + +[Shutdown] +AllowFifo=false +HaltCmd=/usr/bin/systemctl poweroff +RebootCmd=/usr/bin/systemctl reboot + +[Xdmcp] +Enable=false + diff --git a/core/modules/kdm-theme-bwlp/data/etc/systemd/system/kdm-hwinfo-warnings.service b/core/modules/kdm-theme-bwlp/data/etc/systemd/system/kdm-hwinfo-warnings.service new file mode 100644 index 00000000..39f101c8 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/etc/systemd/system/kdm-hwinfo-warnings.service @@ -0,0 +1,9 @@ +[Unit] +Description=Patch warnings into KDM theme +After=hardware-stats.service mount-vm-store.service +Before=kdm.service + +[Service] +Type=oneshot +ExecStart=/opt/openslx/scripts/systemd-kdm_hwinfo_warnings +RemainAfterExit=yes diff --git a/core/modules/kdm-theme-bwlp/data/etc/systemd/system/multi-user.target.wants/kdm-hwinfo-warnings.service b/core/modules/kdm-theme-bwlp/data/etc/systemd/system/multi-user.target.wants/kdm-hwinfo-warnings.service new file mode 120000 index 00000000..e6de5e15 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/etc/systemd/system/multi-user.target.wants/kdm-hwinfo-warnings.service @@ -0,0 +1 @@ +../kdm-hwinfo-warnings.service
\ No newline at end of file diff --git a/core/modules/kdm-theme-bwlp/data/opt/openslx/scripts/systemd-kdm_hwinfo_warnings b/core/modules/kdm-theme-bwlp/data/opt/openslx/scripts/systemd-kdm_hwinfo_warnings new file mode 100755 index 00000000..8b37de80 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/opt/openslx/scripts/systemd-kdm_hwinfo_warnings @@ -0,0 +1,66 @@ +#!/bin/ash + +patch_kdm_theme() { + local THEME_FILE="/usr/share/desktop/themes/kdm/bwlehrpool/theme.xml" + [ -s "$THEME_FILE" ] || return 0 + local TMP=$(mktemp) + [ -z "$TMP" ] && TMP="/tmp/kdm-$$-$(whoami)-$?-$!-tmp" + sed '/INFO_START_MARKER/,/INFO_END_MARKER/{//!d};/INFO_START_MARKER/a REPLACE_MARKER' "$THEME_FILE" > "$TMP" + local DATA= + build_replacement_xml + awk -v r="$DATA" '{gsub(/REPLACE_MARKER/,r)}1' "$TMP" > "$THEME_FILE" +} + +build_replacement_xml() { + local TEMPLATE=' +<item type="label"> + <normal color="_COLOR_" font="Sans 11"/> + <text>_TEXT_</text> +</item>' + . "/run/hwinfo" + local CONTACT_RZ= + # Warning: add_replace_xml doesn't escape <>& (XML), and also doesn't escape , and & (sed), so e.g. < should be written as \< + # Also don't use # as it's the sed delimiter + if [ "$HW_KVM" = "DISABLED" ]; then + add_replace_xml "ff0000" "* 64Bit-Gast-Support (VT-x oder AMD-V) ist im BIOS deaktiviert. 64Bit VMs können nicht gestartet werden." + CONTACT_RZ=jau + elif [ "$HW_KVM" = "UNSUPPORTED" ]; then + add_replace_xml "000000" "* CPU hat keinen 64Bit-Gast-Support (VT-x oder AMD-V). 64Bit VMs können nicht gestartet werden." + fi + if [ -n "$HW_MBRAM" ] && [ "$HW_MBRAM" -lt 3400 ]; then + local GB=$(( ( HW_MBRAM + 300 ) / 1024 )) + add_replace_xml "000000" "* Dieser PC hat wenig RAM (${GB}GB). Die Leistung von VM-Sitzungen wird nicht optimal sein." + fi + if [ "$HW_ID44" = "0" ]; then + add_replace_xml "000000" "* Keine ID44-Partition gefunden. VMs bekommen wenig RAM zugewiesen." + if [ "$HW_HDDCOUNT" = "0" ]; then + add_replace_xml "000000" " Keine Festplatte erkannt; eine Festplatte wird empfohlen, wenn Sie VMs nutzen wollen." + elif [ -n "$HW_HDDCOUNT" ]; then + CONTACT_RZ=klar + fi + if [ -n "$HW_MBRAM" ] && [ "$HW_MBRAM" -lt 4500 ]; then + add_replace_xml "ff0000" " Da der PC wenig RAM hat, ist die Einrichtung einer ID44-Partition dringend zu empfehlen." + fi + elif [ -n "$HW_ID44" ] && [ "$HW_ID44" -lt 10000 ]; then + add_replace_xml "000000" "* Die ID44-Partition ist sehr klein. VM-Sitzungen könnten nach einiger Zeit aus Speichermangel abstürzen." + CONTACT_RZ=fjeden + fi + if ! systemctl status mount-vm-store >/dev/null; then + add_replace_xml "ff0000" "* Der VM-Store konnte nicht eingehängt werden. VMs können nicht gestartet werden." + add_replace_xml "ff0000" " Versuchen Sie das Problem zu lösen, indem Sie den Computer neu starten." + fi + if [ -n "$CONTACT_RZ" ]; then + add_replace_xml "000000" " -- " + add_replace_xml "000000" " -- Wenden Sie sich ggf. an den bwLehrpool-Support Ihres Rechenzentrums -- " + fi +} + +add_replace_xml() { + [ -z "$DATA" ] && DATA=$(echo "$TEMPLATE" | sed "s,_COLOR_,#000000,;s,_TEXT_,Hinweise für den Admin/Hardware-Betreuer:,") + DATA="$DATA $(echo "$TEMPLATE" | sed "s,_COLOR_,#$1,;s#_TEXT_#$2#")" +} + + + +patch_kdm_theme + diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/KdmGreeterTheme.desktop b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/KdmGreeterTheme.desktop new file mode 100644 index 00000000..6ebf8249 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/KdmGreeterTheme.desktop @@ -0,0 +1,7 @@ +[KdmGreeterTheme] +Encoding=UTF-8 +Greeter=theme.xml +Name=bwLehrpool KDM theme +Description=Basic bwLehrpool KDM Theme +Author=Base by aceph <aceph@ventcore.net>, modified by MJanc, sr +Copyright=Creative Commons diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/bwLehrpool-white.svg b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/bwLehrpool-white.svg new file mode 100644 index 00000000..f0d1a539 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/bwLehrpool-white.svg @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + width="149.62437" + height="92.827499" + id="svg2985" + xml:space="preserve"><metadata + id="metadata2991"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs2989"><clipPath + id="clipPath3001"><path + d="M 0,8356.66 0,0 l 4518.7,0 0,8356.66 -4518.7,0 z" + id="path3003" /></clipPath></defs><g + transform="matrix(1.25,0,0,-1.25,-71.388125,593.675)" + id="g2993"><g + id="g3763"><path + d="m 107.979,438.637 -27.1091,0 0,11.032 21.5941,0 0,10.688 11.032,0 0,-16.204 c 0,-3.047 -2.469,-5.516 -5.517,-5.516" + id="path3065" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 122.466,400.678 -10.537,0 0,25.76 c 0.127,2.954 2.557,5.284 5.513,5.284 l 59.368,0 0,-11.033 -54.08,0 -0.264,-20.011" + id="path3067" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 104.061,409.795 -11.109,0 -0.109,10.894 -35.7325,0 0,11.033 41.434,0 c 1.4935,0 2.9235,-0.607 3.9645,-1.681 1.038,-1.074 1.597,-2.523 1.549,-4.018 l 0.003,-16.228" + id="path3069" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 146.076,438.57 -20.455,0 c -3.046,0 -5.517,2.471 -5.517,5.518 l 0,30.852 11.033,0 0,-25.336 14.939,0 0,-11.034" + id="path3071" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></svg>
\ No newline at end of file diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/bwLehrpool.svg b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/bwLehrpool.svg new file mode 100644 index 00000000..8b6a2308 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/bwLehrpool.svg @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + width="564.83734" + height="131.315" + id="svg2985" + xml:space="preserve"><metadata + id="metadata2991"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs2989"><clipPath + id="clipPath3001"><path + d="M 0,8356.66 0,0 l 4518.7,0 0,8356.66 -4518.7,0 z" + id="path3003" /></clipPath></defs><g + transform="matrix(1.25,0,0,-1.25,0,1044.5825)" + id="g2993"><g + id="g3598"><path + d="m 71.6785,784.102 -38.1996,0 0,15.545 30.4273,0 0,15.061 15.5458,0 0,-22.834 c 0,-4.294 -3.4786,-7.772 -7.7735,-7.772" + id="path3009" + style="fill:#f9a72b;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 92.0914,730.614 -14.8469,0 0,36.3 c 0.1778,4.161 3.6028,7.444 7.7688,7.444 l 83.6537,0 0,-15.546 -76.2041,0 -0.3715,-28.198" + id="path3011" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 66.1566,743.461 -15.6531,0 -0.1539,15.351 -50.3496,0 0,15.546 58.384,0 c 2.1047,0 4.1203,-0.854 5.5867,-2.369 1.4629,-1.513 2.25,-3.554 2.1816,-5.661 l 0.0043,-22.867" + id="path3013" + style="fill:#f9a72b;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 125.361,784.008 -28.8239,0 c -4.2922,0 -7.7742,3.481 -7.7742,7.775 l 0,43.473 15.5481,0 0,-35.7 21.05,0 0,-15.548" + id="path3015" + style="fill:#f9a72b;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 153.667,815.973 c -7.762,0 -10.206,-7.619 -10.206,-14.159 0,-6.756 1.94,-14.16 10.206,-14.16 7.691,0 10.207,7.404 10.207,14.16 0,6.756 -2.013,14.159 -10.207,14.159 z m -10.35,-32.2 -7.043,0 c 0.143,2.157 0.359,4.313 0.359,5.749 l 0,46.144 6.828,0 0,-20.699 0.144,0 c 2.084,4.312 6.612,5.965 11.213,5.965 11.212,0 16.244,-9.344 16.244,-19.118 0,-9.273 -4.313,-19.119 -15.022,-19.119 -5.248,0 -9.991,1.797 -12.435,6.827 l -0.144,0 0.144,-0.359 -0.288,-5.39" + id="path3017" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 233.448,819.854 -12.722,-36.081 -7.763,0 -8.409,29.684 -0.143,0 -9.344,-29.684 -7.979,0 -11.931,36.081 7.403,0 8.697,-29.038 0.144,0 8.985,29.038 8.84,0 8.122,-28.462 0.144,0 8.984,28.462 6.972,0" + id="path3019" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 239.055,783.773 0,51.893 4.6,0 0,-48.012 17.178,0 0,-3.881 -21.778,0" + id="path3021" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 286.346,804.473 c 0,8.05 -1.294,12.865 -8.193,12.865 -6.9,0 -8.195,-4.815 -8.195,-12.865 l 16.388,0 z m -16.388,-3.45 0,-2.803 c 0,-5.032 1.367,-11.715 8.195,-11.715 5.39,0 8.049,3.449 7.977,8.337 l 4.529,0 c -0.504,-8.769 -5.247,-11.788 -12.506,-11.788 -6.253,0 -12.507,2.516 -12.507,13.512 l 0,8.914 c 0,10.493 4.386,15.308 12.507,15.308 12.506,0 12.506,-8.984 12.506,-19.765 l -20.701,0" + id="path3023" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 298.493,783.773 0,51.893 4.312,0 0,-20.052 0.145,0 c 2.085,3.018 4.887,5.174 8.766,5.174 8.987,0 9.921,-6.683 9.921,-11.428 l 0,-25.587 -4.313,0 0,25.372 c 0,4.241 -1.654,8.193 -6.685,8.193 -3.882,0 -7.834,-2.658 -7.834,-10.78 l 0,-22.785 -4.312,0" + id="path3025" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 335.002,815.183 0.145,0 c 1.797,3.449 5.606,5.605 9.99,5.605 l 0,-4.383 c -6.109,0.502 -10.135,-3.163 -10.135,-9.273 l 0,-23.359 -4.312,0 0,36.297 4.312,0 0,-4.887" + id="path3027" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 354.842,798.723 c 0,-8.266 3.739,-12.218 7.691,-12.218 5.965,0 6.971,3.952 7.331,4.815 0.719,1.797 0.863,8.338 0.863,10.638 0,7.187 0,15.38 -7.689,15.38 -3.307,0 -8.196,-3.162 -8.196,-12.146 l 0,-6.469 z m -0.143,16.963 0.143,0.072 c 2.3,3.521 5.895,5.03 8.768,5.03 11.356,0 11.43,-9.918 11.43,-14.662 l 0,-8.122 c 0,-9.416 -3.236,-14.95 -12.507,-14.95 -2.66,0 -5.318,1.294 -7.547,4.744 l -0.144,0.073 0,-17.826 -4.312,0 0,50.025 4.169,0 0,-4.384" + id="path3029" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 401.2,791.32 c 0.718,1.797 0.863,8.338 0.863,10.638 0,10.708 -1.079,15.38 -8.195,15.38 -7.116,0 -8.195,-4.672 -8.195,-15.38 0,-2.3 0.145,-8.841 0.864,-10.638 0.359,-0.863 1.366,-4.815 7.331,-4.815 5.965,0 6.972,3.952 7.332,4.815 z m -19.839,6.684 0,8.625 c 0,4.6 0.071,14.159 12.507,14.159 12.435,0 12.507,-9.559 12.507,-14.159 l 0,-8.625 c 0,-9.416 -3.235,-14.95 -12.507,-14.95 -9.271,0 -12.507,5.534 -12.507,14.95" + id="path3031" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 433.113,791.32 c 0.718,1.797 0.862,8.338 0.862,10.638 0,10.708 -1.079,15.38 -8.194,15.38 -7.116,0 -8.195,-4.672 -8.195,-15.38 0,-2.3 0.145,-8.841 0.863,-10.638 0.359,-0.863 1.366,-4.815 7.332,-4.815 5.965,0 6.972,3.952 7.332,4.815 z m -19.839,6.684 0,8.625 c 0,4.6 0.071,14.159 12.507,14.159 12.434,0 12.506,-9.559 12.506,-14.159 l 0,-8.625 c 0,-9.416 -3.235,-14.95 -12.506,-14.95 -9.273,0 -12.507,5.534 -12.507,14.95" + id="path3033" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path + d="m 447.557,783.773 4.31289,0 0,51.893 -4.31289,0 0,-51.893 z" + id="path3035" + style="fill:#888687;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></svg>
\ No newline at end of file diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/enter.png b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/enter.png Binary files differnew file mode 100644 index 00000000..b646e851 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/enter.png diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/enter_inactive.png b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/enter_inactive.png Binary files differnew file mode 100644 index 00000000..e12cfb8e --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/enter_inactive.png diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/system.png b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/system.png Binary files differnew file mode 100644 index 00000000..4857b941 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/system.png diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/system_inactive.png b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/system_inactive.png Binary files differnew file mode 100644 index 00000000..28f0251f --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/system_inactive.png diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/theme.xml b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/theme.xml new file mode 100644 index 00000000..6aaac6b3 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/theme.xml @@ -0,0 +1,196 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE greeter SYSTEM "greeter.dtd"> +<!-- +KDM-OpenSLX-Theme +--> +<greeter id="theme"> + <style font="Sans 11" window-text-color="#f0f0f0" base-color="#f0f0f0" text-color="#000000"/> + <!-- background --> + <item type="rect" id="background" background="true"> + <normal color="#e3e4e9" alpha="1.0"/> + <pos x="0" y="0" width="100%" height="100%"/> + </item> + <!-- top / welcome, clock and big logo --> + <item type="rect" id="top" background="true"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="n" x="50%" y="0" width="100%" height="45%"/> + <box orientation="vertical" homogeneous="true"> + <item type="pixmap"> + <normal file="top-bar.png"/> + <pos anchor="n" x="50%" y="0" width="80%" height="50"/> + <box orientation="horizontal" homogeneous="true"> + <!-- Welcome on ... --> + <item type="label"> + <pos anchor="w" x="12%" y="11"/> + <normal color="#f0f0f0" font="Sans 11"/> + <stock type="welcome-label"/> + </item> + <!-- clock --> + <item type="label" id="clock"> + <pos anchor="e" x="88%" y="11"/> + <normal color="#f0f0f0" font="Sans 11"/> + <text>%c</text> + </item> + </box> + </item> + <item type="rect" id="logo"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="s" x="50%" y="50%" width="100%" height="100%"/> + <box orientation="vertical" homogeneous="true"> + <item type="pixmap" background="true"> + <normal file="bwLehrpool.svg" scalemode="fit"/> + <pos anchor="c" x="50%" y="50%" height="100%" width="100%"/> + </item> + </box> + </item> + </box> + </item> + <!-- main part / login, session, menu, ... --> + <item type="rect" id="main-runner" background="true"> + <normal color="#757575" alpha="1.0"/> + <pos anchor="c" x="50%" y="50%" width="100%" height="160"/> + <box orientation="horizontal" homogeneous="true"> + <item type="rect" background="true"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="w" x="0%" y="50%" width="100%" height="100%"/> + <box orientation="horizontal" homogeneous="true"> + <!-- left part / login --> + <item type="rect" background="true"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="w" x="0" y="50%" width="100%" height="100%"/> + <box orientation="horizontal"> + <!-- small logo --> + <item type="pixmap"> + <normal file="bwLehrpool-white.svg" scalemode="fit"/> + <pos anchor="w" x="20" y="50%" width="80" height="100%"/> + </item> + <!-- login --> + <item type="rect"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="w" x="40" y="50%" width="box" height="box"/> + <box orientation="horizontal" spacing="10"> + <item type="rect"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="sw" x="0" y="100%" width="box" height="100%"/> + <box homogeneous="true" spacing="10"> + <!-- username-label --> + <item type="label"> + <pos anchor="nw" x="0" y="0"/> + <normal color="#f0f0f0" font="Sans 11"/> + <stock type="username-label"/> + </item> + <!-- password-label --> + <item type="label"> + <pos anchor="sw" x="0" y="-0"/> + <normal color="#f0f0f0" font="Sans 11"/> + <stock type="password-label"/> + </item> + </box> + </item> + <item type="rect"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="nw" x="0" y="0" width="box" height="box"/> + <box homogeneous="true" spacing="10"> + <!-- username-entry --> + <item type="entry" id="user-entry"> + <pos anchor="w" x="0" y="50%" height="20" width="200"/> + </item> + <!-- password-entry --> + <item type="entry" id="pw-entry"> + <pos anchor="w" x="0" y="50%" height="20" width="200"/> + </item> + </box> + </item> + <item type="pixmap" button="true" id="login_button"> + <pos anchor="sw" x="0" y="-0" height="20" width="20"/> + <normal file="enter_inactive.png"/> + <prelight file="enter.png"/> + </item> + </box> + </item> + </box> + </item> + <!-- middle part / errors, caps info, kdm logo --> + <item type="rect"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="c" x="50%" y="50%" width="90%" height="100%"/> + <box orientation="vertical"> + <!-- Login-Error --> + <item type="rect"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="n" x="50%" y="10" width="100%" height="30"/> + <box> + <item type="label" id="pam-error"> + <normal color="#ff8b00" font="Sans 11"/> + <pos anchor="c" x="50%" y="15"/> + <text/> + </item> + </box> + </item> + <!-- capslock-warning --> + <item type="rect" id="caps-lock-warning"> + <normal color="#000000" alpha="0.4"/> + <pos anchor="s" x="50%" y="-10" width="100%" height="30"/> + <box> + <item type="label"> + <normal color="#ff8b00" font="Sans 11"/> + <pos anchor="c" x="50%" y="15"/> + <stock type="caps-lock-warning"/> + </item> + </box> + </item> + </box> + </item> + <!-- right part / sessions, menu --> + <item type="rect"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="e" x="100%" y="50%" width="100%" height="50%"/> + <box orientation="vertical" homogeneous="true" spacing="10"> + <!-- menu-button --> + <item type="rect" id="system_button" button="true"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="e" x="90%" y="50%" width="box" height="box"/> + <box orientation="horizontal"> + <item type="label"> + <normal color="#bbbbbb" font="Sans 11"/> + <prelight color="#f0f0f0" font="Sans 11"/> + <active color="#ff8b00" font="Sans 11"/> + <pos anchor="e" x="100%" y="24"/> + <stock type="system"/> + </item> + <item type="rect" id="system_button" button="true"> + <normal color="#000000" alpha="0.0"/> + <pos anchor="c" x="50%" y="50%" width="10"/> + </item> + <item type="pixmap" id="system_button" button="true"> + <normal file="system_inactive.png"/> + <prelight file="system.png"/> + <pos anchor="ne" x="100%" y="0%"/> + </item> + </box> + </item> + </box> + </item> + </box> + </item> + </box> + </item> + <!-- dynamic info --> + <item type="rect"> + <pos anchor="s" x="50%" y="100%" width="66%" height="30%"/> + <box> + <!-- INFO_START_MARKER --> + <!-- INFO_END_MARKER --> + </box> + </item> + <!-- Icon/Logo of Uni --> + <item type="pixmap" id="branding_logo" button="false"> + <normal file="/etc/branding.svg" scalemode="fit"/> + <pos anchor="sw" x="1%" y="99%" width="13%" height="13%"/> + </item> + <!-- Icon/Logo of Base Distro --> + <item type="pixmap" id="distro_logo" button="false"> + <normal file="/etc/distro.png" alpha="0.8"/> + <pos anchor="se" x="99%" y="99%"/> + </item> +</greeter> diff --git a/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/top-bar.png b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/top-bar.png Binary files differnew file mode 100644 index 00000000..0c89dbef --- /dev/null +++ b/core/modules/kdm-theme-bwlp/data/usr/share/desktop/themes/kdm/bwlehrpool/top-bar.png diff --git a/core/modules/kdm-theme-bwlp/module.build b/core/modules/kdm-theme-bwlp/module.build new file mode 100644 index 00000000..ccb7c4e1 --- /dev/null +++ b/core/modules/kdm-theme-bwlp/module.build @@ -0,0 +1,13 @@ + +fetch_source () { + : +} + +build () { + : +} + +post_copy() { + : +} + diff --git a/core/modules/kdm-theme-bwlp/module.conf b/core/modules/kdm-theme-bwlp/module.conf new file mode 100644 index 00000000..04a7b61d --- /dev/null +++ b/core/modules/kdm-theme-bwlp/module.conf @@ -0,0 +1,2 @@ +REQUIRED_MODULES="kdm" + diff --git a/core/modules/kdm/data/etc/kde4/kdm/kdmrc b/core/modules/kdm/data/etc/kde4/kdm/kdmrc index 5f9f9e39..b14a7929 100644 --- a/core/modules/kdm/data/etc/kde4/kdm/kdmrc +++ b/core/modules/kdm/data/etc/kde4/kdm/kdmrc @@ -3,6 +3,7 @@ PidFile=/var/run/kdm.pid ServerVTs=-7 # Always spawn :0 (this is the default but it won't hurt) StaticServers=:0 +GreeterUID=kdm [X-*-Greeter] UseTheme=true diff --git a/core/modules/kdm/module.conf.debian b/core/modules/kdm/module.conf.debian index 2b1ca00d..233598d8 100644 --- a/core/modules/kdm/module.conf.debian +++ b/core/modules/kdm/module.conf.debian @@ -22,8 +22,8 @@ REQUIRED_DIRECTORIES+=" " # non-standard vars REQUIRED_SYSTEM_FILES+=" - /usr/share/kde4/apps/kdm/pics/shutdown.png /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf + /usr/share/kde4/apps/kdm/pics/shutdown.png /usr/share/icons/default/index.theme " diff --git a/core/modules/kdm/module.conf.ubuntu b/core/modules/kdm/module.conf.ubuntu index 660b3a1e..0e177c51 100644 --- a/core/modules/kdm/module.conf.ubuntu +++ b/core/modules/kdm/module.conf.ubuntu @@ -5,7 +5,7 @@ REQUIRED_INSTALLED_PACKAGES=" REQUIRED_CONTENT_PACKAGES=" kdm kde-workspace-kgreet-plugins - libicu48 + libicu52 libxcursor1 libxrandr2 libxfixes3 diff --git a/core/modules/kdm/module.conf.ubuntu.12 b/core/modules/kdm/module.conf.ubuntu.12 new file mode 100644 index 00000000..80d59bf3 --- /dev/null +++ b/core/modules/kdm/module.conf.ubuntu.12 @@ -0,0 +1,27 @@ +REQUIRED_INSTALLED_PACKAGES=" + kdm + kde-workspace-kgreet-plugins +" +REQUIRED_CONTENT_PACKAGES=" + kdm + kde-workspace-kgreet-plugins + libicu48 + libxcursor1 + libxrandr2 + libxfixes3 + libxinerama1 + libxi6 +" +REQUIRED_DIRECTORIES+=" + /usr/lib + /etc/pam.d + /etc/logrotate.d + /etc/insserv.conf.d + /etc/kde4/kdm +" +# non-standard vars +REQUIRED_SYSTEM_FILES+=" + /usr/share/kde4/apps/kdm/pics/shutdown.png + /usr/share/icons/default/index.theme +" + diff --git a/core/modules/kernel-vanilla/module.build b/core/modules/kernel-vanilla/module.build index 66906fb7..7a6052fc 100644 --- a/core/modules/kernel-vanilla/module.build +++ b/core/modules/kernel-vanilla/module.build @@ -4,21 +4,22 @@ get_kernel_version() { # Do not use MODULE_DIR here as this function might run when we process another module! [ -n "${TARGET_KERNEL_LONG}" ] && return 0 - [ ! -e "${TARGET_DIR}/kernel/ksrc/include/generated/utsrelease.h" ] && return 0 + [ ! -e "${ROOT_DIR}/tmp/work/kernel/ksrc/include/generated/utsrelease.h" ] && pinfo "No UTS information" && return 0 # determine kernel version that will be running in the generated system # declare kernel version stuff - declare -rg TARGET_KERNEL_LONG=$(grep 'UTS_RELEASE' "${TARGET_DIR}/kernel/ksrc/include/generated/utsrelease.h" | awk -F '"' '{print $2}') + declare -rg TARGET_KERNEL_LONG=$(grep 'UTS_RELEASE' "${ROOT_DIR}/tmp/work/kernel/ksrc/include/generated/utsrelease.h" | awk -F '"' '{print $2}') declare -rg TARGET_KERNEL_SHORT=$(echo "$TARGET_KERNEL_LONG" | grep -o -E '^[0-9\.]+') # declare path to kernel headers and modules/firmware - declare -rg KERNEL_HEADERS_DIR="${TARGET_DIR}/kernel/ksrc" - declare -rg KERNEL_BASE_DIR="${TARGET_DIR}/kernel/build" + declare -rg KERNEL_HEADERS_DIR="${ROOT_DIR}/tmp/work/kernel/ksrc" + declare -rg KERNEL_BASE_DIR="${ROOT_DIR}/tmp/work/kernel/build" # print debug info pinfo "TARGET_KERNEL_LONG: '$TARGET_KERNEL_LONG'" pinfo "TARGET_KERNEL_SHORT: '$TARGET_KERNEL_SHORT'" pdebug "KERNEL_BASE_DIR: '$KERNEL_BASE_DIR'" + pdebug "KERNEL_HEADERS_DIR: '$KERNEL_HEADERS_DIR'" } fetch_source() { @@ -123,7 +124,7 @@ patch_aufs() { local KERNEL_MAJOR=${REQUIRED_KERNEL%%.*} local AUFS="aufs${KERNEL_MAJOR}" pinfo "Cloning ${AUFS} standalone git" - cd "$MODULE_WORK_DIR" + cd "${MODULE_WORK_DIR}" [ -d "${AUFS}-standalone/.git" ] && rm -rf "${AUFS}-standalone" # if already there, kill it. # git: --depth 1 won't work here due to later "checkout origin/branch" if [ "$KERNEL_MAJOR" = "3" ]; then @@ -135,7 +136,7 @@ patch_aufs() { [ -n "${SYSTEM_KERNEL_LONG}" ] && local NEEDED_BRANCH=$(echo $REQUIRED_KERNEL | awk -F "." '{print $1"."$2}') \ || perror "REQUIRED_KERNEL not set, this should not happen!" pinfo "Getting branch origin/$NEEDED_BRANCH" - cd "$MODULE_WORK_DIR/${AUFS}-standalone" || perror "Could not CD to ${AUFS}-standalone" + cd "${MODULE_WORK_DIR}/${AUFS}-standalone" || perror "Could not CD to ${AUFS}-standalone" git checkout "origin/aufs$NEEDED_BRANCH" || git checkout "origin/aufs4.x-rcN" || perror "Could not checkout needed branch." pinfo "Starting to patch... $NEEDED_BRANCH" tarcopy "Documentation fs" "$MODULE_WORK_DIR/ksrc" @@ -160,6 +161,5 @@ patch_aufs() { done pinfo "Patched kernel source with aufs-${NEEDED_BRANCH}" cd "$MODULE_WORK_DIR" - } diff --git a/core/modules/kernel-vanilla/module.conf b/core/modules/kernel-vanilla/module.conf index b615dc9b..5f72c5f2 100644 --- a/core/modules/kernel-vanilla/module.conf +++ b/core/modules/kernel-vanilla/module.conf @@ -1,5 +1,5 @@ REQUIRED_BINARIES="" REQUIRED_LIBRARIES="" REQUIRED_DIRECTORIES="" -REQUIRED_KERNEL="4.3.5" +REQUIRED_KERNEL="4.9" REQUIRED_GIT="git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git" diff --git a/core/modules/ncp/FIXME b/core/modules/ncp/FIXME new file mode 100644 index 00000000..d5e788aa --- /dev/null +++ b/core/modules/ncp/FIXME @@ -0,0 +1,2 @@ +This module is broken as of 07.12.16, as the hardcoded urls to the deb packages are dead. +Why was this pursued instead of using the regular package manager way? diff --git a/core/modules/nvidia_kernel/module.build b/core/modules/nvidia_kernel/module.build index b091eab2..5eb7161d 100644 --- a/core/modules/nvidia_kernel/module.build +++ b/core/modules/nvidia_kernel/module.build @@ -39,7 +39,7 @@ build() { local NVIDIA_MODULES="$MODULE_BUILD_DIR/lib/modules/nvidia/" mkdir -p "$NVIDIA_MODULES" pinfo "Copying kernel modules..." - for file in nvidia.ko nvidia-uvm.ko nvidia-modeset.ko; do + for file in nvidia.ko nvidia-uvm.ko nvidia-modeset.ko nvidia-drm.ko; do RESULT=$(find "$ROOTUPPERDIR/NVIDIA/kernel" -name "$file" | head -n 1) [ -z "$RESULT" ] && perror "Could not find built module $file in ./NVIDIA/kernel" pinfo "Fetching ${file}..." diff --git a/core/modules/nvidia_kernel/module.conf b/core/modules/nvidia_kernel/module.conf index d04051b9..68ab2a9a 100644 --- a/core/modules/nvidia_kernel/module.conf +++ b/core/modules/nvidia_kernel/module.conf @@ -1,4 +1,4 @@ -REQUIRED_VERSION="358.16" +REQUIRED_VERSION="375.26" REQUIRED_NVIDIA="NVIDIA-Linux-x86_64-$REQUIRED_VERSION.run" REQUIRED_URL="http://download.nvidia.com/XFree86/Linux-x86_64/$REQUIRED_VERSION/$REQUIRED_NVIDIA" diff --git a/core/modules/nvidia_libs/module.build b/core/modules/nvidia_libs/module.build index 7f8a9444..5134e824 100644 --- a/core/modules/nvidia_libs/module.build +++ b/core/modules/nvidia_libs/module.build @@ -2,11 +2,11 @@ fetch_source() { mkdir -p src cd src || perror "Could not change into src directory." download "$REQUIRED_URL" + cd .. } build() { - local KERNELSRCDIR="$MODULE_WORK_DIR/../kernel/ksrc" # kernel sources - local NVIDIA="$MODULE_WORK_DIR/src/$REQUIRED_NVIDIA" + local NVIDIA="${MODULE_WORK_DIR}/src/$REQUIRED_NVIDIA" local NVIDIAEXTRACTDIR="$MODULE_BUILD_DIR/NVIDIA" pdebug "Unpacking NVidia-Installer ..." @@ -36,16 +36,6 @@ build() { mv "${MODULE_BUILD_DIR}/overlay.whiteout.list" "${MODULE_BUILD_DIR}/opt/openslx/etc/nvidia.whiteout" fi - #pdebug "Handling whiteouts ..." - #local WHITEOUT_LIST="${MODULE_BUILD_DIR}/opt/openslx/etc/nvidia.whiteout" - #rm -f -- "$WHOUTEOUT_LIST" - #mkdir -p "$(dirname "$WHITEOUT_LIST")" || perror "Could not create $(dirname "$WHITEOUT_LIST")" - #pdebug "Searching for overlayfs-whiteouts ..." - #for WHITEOUT in $(find "$MODULE_BUILD_DIR" -lname "(overlay-whiteout)"); do -# pdebug "Whiteout found: $WHITEOUT" -# echo "/./${WHITEOUT#$MODULE_BUILD_DIR}" >> "$WHITEOUT_LIST" -# rm -f -- "$WHITEOUT" || perror "Could not delete whiteout $WHITEOUT!" -# done rm -rf "$MODULE_BUILD_DIR/NVIDIA" } diff --git a/core/modules/nvidia_libs/module.conf b/core/modules/nvidia_libs/module.conf index a2f017ca..8032b6e4 100644 --- a/core/modules/nvidia_libs/module.conf +++ b/core/modules/nvidia_libs/module.conf @@ -1,4 +1,4 @@ -REQUIRED_VERSION="358.16" +REQUIRED_VERSION="375.26" REQUIRED_NVIDIA="NVIDIA-Linux-x86_64-$REQUIRED_VERSION.run" REQUIRED_URL="http://download.nvidia.com/XFree86/Linux-x86_64/$REQUIRED_VERSION/$REQUIRED_NVIDIA" diff --git a/core/modules/openbox/data/etc/xdg/openbox/menu.xml b/core/modules/openbox/data/etc/xdg/openbox/menu.xml index 866969f6..d563f1f0 100644 --- a/core/modules/openbox/data/etc/xdg/openbox/menu.xml +++ b/core/modules/openbox/data/etc/xdg/openbox/menu.xml @@ -9,8 +9,8 @@ <item label="Terminal"> <action name="Execute"><execute>xterm</execute></action> </item> - <item label="VM Chooser"> - <action name="Execute"><execute>vmchooser -c /etc/openslx/vmchooser/vmchooser.conf</execute></action> + <item label="VMChooser"> + <action name="Execute"><execute>vmchooser</execute></action> </item> <!-- This requires the presence of the 'menu' package to work --> <menu id="/Debian" /> diff --git a/core/modules/pam-bwidm/data/opt/openslx/bwidm_soap.xml b/core/modules/pam-bwidm/data/opt/openslx/bwidm_soap.xml new file mode 100644 index 00000000..ec7f3ff8 --- /dev/null +++ b/core/modules/pam-bwidm/data/opt/openslx/bwidm_soap.xml @@ -0,0 +1,14 @@ +<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> + <S:Body> + <samlp:AuthnRequest + xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" + AssertionConsumerServiceURL="https://bwlp-masterserver.ruf.uni-freiburg.de/Shibboleth.sso/SAML2/ECP" + ID="%REQUESTID%" + IssueInstant="%TIMESTAMP%" + ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" + Version="2.0"> + <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://bwlp-masterserver.ruf.uni-freiburg.de/shibboleth</saml:Issuer> + <samlp:NameIDPolicy AllowCreate="1"/> + </samlp:AuthnRequest> + </S:Body> +</S:Envelope> diff --git a/core/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm b/core/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm new file mode 100755 index 00000000..92379719 --- /dev/null +++ b/core/modules/pam-bwidm/data/opt/openslx/scripts/pam_bwidm @@ -0,0 +1,218 @@ +#!/bin/ash +# +# This script is to be called by PAM (specifically pam_exec). +# We expect the username in the form: username@organisation +# If it is in that form, we will query the masterserver for the list +# of supported IdPs and if one matches the user's organisation +# we will try to authenticate against it. + +# fix PATH as PAM clears it +export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin" + +# grab the password from stdin asap, since there is no guarantee some tool just reads it +unset USER_PASSWORD +if [ "x$PAM_TYPE" == "xauth" ]; then + read -r USER_PASSWORD > /dev/null 2>&1 + readonly USER_PASSWORD + [ -z "$USER_PASSWORD" ] && echo "No password given." && exit 1 +fi + +if ! busybox which curl || ! busybox which mktemp; then + echo "'curl/mktemp' missing. This script won't work without it." + exit 1 +fi + +# redirect stdout/stderr to temporary logfile +readonly LOGFILE="$(mktemp)" +# URL to query masterserver for IDPs +readonly IDP_QUERY_URL="https://bwlp-masterserver.ruf.uni-freiburg.de/webif/pam.php" +readonly IDP_QUERY_CACHE="/run/openslx/bwlp-idp" + +# everything in a subshell in an effort to hide sensitive information +# from this script's environment +( +# redirect stdout and stderr to logfile +exec > "${LOGFILE}" 2>&1 + +# check if we are allowed to run +. /opt/openslx/config +if [ "x${SLX_BWIDM_AUTH}" = "xyes" ]; then + : # Allow everything +elif [ "x${SLX_BWIDM_AUTH}" = "xselective" ]; then + if [ -z "${SLX_BWIDM_ORGS}" ]; then + echo "bwIDM selective mode with empty org list - exiting" + exit 1 + fi +else + echo "bwIDM login disabled in openslx-config." + exit 1 +fi + +# sanity check on PAM_USER: contains '@'? +if [ -z "$PAM_USER" ] || [ "x${PAM_USER}" == "x${PAM_USER%@*}" ]; then + # no @ contained, invalid username, abort + echo "Invalid username '$PAM_USER'. Aborting." + exit 1 +fi + +# valid username, we can already split it here +readonly USER_USERNAME="${PAM_USER%@*}" +readonly USER_ORGANISATION="${PAM_USER#*@}" +[ -z "$USER_ORGANISATION" ] && echo "Could not parse organisation from given login: ${PAM_USER}. Aborting." && exit 1 +[ -z "$USER_USERNAME" ] && echo "Could not parse user from given login: ${PAM_USER}. Aborting." && exit 1 + +# Check if we're in selective mode and if so, whether the user's organization is whitelisted +if [ "x${SLX_BWIDM_AUTH}" = "xselective" ]; then + FOUND= + for org in ${SLX_BWIDM_ORGS}; do + if [ "x$org" = "x$USER_ORGANISATION" ]; then + FOUND=ya + break + fi + done + if [ -z "$FOUND" ]; then + echo "bwIDM organization $USER_ORGANISATION not in whitelist, abort" + exit 1 + fi +fi + +# The given username is valid. Now we get the list of IdPs from the bwlp masterserver +# and try to find the user's organisation + +mkdir -p /run/openslx + +# check if we have a (non-zero bytes) cached copy of the list +if [ ! -s "${IDP_QUERY_CACHE}" ]; then + idpret="$(curl -w "%{http_code}" -o "${IDP_QUERY_CACHE}" --connect-timeout 5 --max-time 15 "$IDP_QUERY_URL")" + if [ "x$idpret" != "x200" ]; then + echo "Could not download the list of identity providers from '$IDP_QUERY_URL'. Aborting." + rm -f -- "$IDP_QUERY_CACHE" + exit 7 + fi +fi +# here we have the cache for sure, search for the given organisation's ECP URL +USER_ECP_URL="$(awk -v idp="${USER_ORGANISATION}" -F '=' '{if($1==idp) print $2}' < "$IDP_QUERY_CACHE")" +[ -z "$USER_ECP_URL" ] && echo "Could not determine ECP URL for '${USER_ORGANISATION}'" && exit 1 + +# recap: here we have validated +# - username +# - organisation +# - ECP URL for that organisation + +# now create the bwidm group: find the first free GID from 1000 "downwards" to 100 +BWIDM_GROUP="$(getent group bwidm)" +if [ -z "$BWIDM_GROUP" ]; then + BWIDM_GID=999 + while [ "$BWIDM_GID" -gt 100 ]; do + getent group "$BWIDM_GID" || break + let BWIDM_GID-- + done + if [ "$BWIDM_GID" -eq 100 ]; then + # use demo's gid as a fallback + readonly BWIDM_GID="$(id -g "demo")" + [ -z "$BWIDM_GID" ] && echo "Could not determine the GID of 'demo'. Cannot use it as fallback. Aborting." && exit 1 + fi + + # now create the group + if ! echo "bwidm:x:$BWIDM_GID:" >> /etc/group; then + echo "Could not create 'bwidm' group with gid '$BWIDM_GID'. Aborting." + exit 1 + fi +else + readonly BWIDM_GID="$(echo $BWIDM_GROUP | cut -d: -f3)" +fi +if [ -z "$BWIDM_GID" ]; then + echo "Could not determine BWIDM-GID. Aborting." + exit 1 +fi +readonly USER_GID="$BWIDM_GID" + +# path to the SOAP envelope we are gonna need soon +readonly SOAP_ENVELOPE="/opt/openslx/bwidm_soap.xml" +[ ! -f "${SOAP_ENVELOPE}" ] && echo "Failed to find the SOAP envelope at '${SOAP_ENVELOPE}'. Aborting." && exit 1 + +# now the pam-type specific part starts +if [ "x$PAM_TYPE" == "xauth" ]; then + HA='Accept: text/html; application/vnd.paos+xml' + HP='PAOS: ver="urn:liberty:paos:2003-08";"urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"' + CT='Content-Type: application/vnd.paos+xml; charset=utf-8' + NOW=$(date -u '+%Y-%m-%dT%H:%M:%SZ') + HOST=$(echo "${USER_ECP_URL}" | awk -F '/' '{print $3}') + RID="_c${RANDOM}a${RANDOM}f${RANDOM}f${RANDOM}e${RANDOM}e${RANDOM}" + RID="${RID:0:32}" + REQUEST=$(sed "s/%TIMESTAMP%/${NOW}/g;s/%REQUESTID%/${RID}/g" "${SOAP_ENVELOPE}") + NETRC=$(mktemp -p /run/) + [ -z "$NETRC" ] && NETRC="/run/netrc_$$_${USER}_${RANDOM}.tmp" + touch "$NETRC" + chmod 0600 "$NETRC" + # now we are ready to actually send the credentials to the IdP + # to be sure everything is working as expected + # we will first send a wrong password and expect a 401 + echo "machine ${HOST} login ${USER_USERNAME} password ___invalid-INVALID++~" > "${NETRC}" + ret=$(curl --connect-timeout 5 --max-time 15 -o /dev/null -w "%{http_code}" -d "${REQUEST}" -H "$CT" -H "$HP" -H "$HA" --basic --netrc-file "$NETRC" "$USER_ECP_URL") + + if [ "x$ret" != "x401" ]; then + # this means something else is bad, just exit + echo "False authentication attempt did not return 401 as expected but: $ret" + rm -- "${NETRC}" + exit 7 + fi + # the fake auth call behaved as expected, do the actualy login + echo "machine ${HOST} login ${USER_USERNAME} password ${USER_PASSWORD}" > "${NETRC}" + ret=$(curl --connect-timeout 5 --max-time 15 -o /dev/null -w "%{http_code}" -d "${REQUEST}" -H "$CT" -H "$HP" -H "$HA" --basic --netrc-file "$NETRC" "$USER_ECP_URL") + echo "machine ${HOST} login ${USER_USERNAME} password ********************" > "${NETRC}" # It should be a tmpfs but you never know + rm -- "${NETRC}" + + if [ "x$ret" == "x200" ]; then + # auth succeeded, lets create a local user representing the bwIDM user + echo "Login for '$USER_USERNAME' on '$USER_ORGANISATION' succeeded." + # create a random 6digit UID + LOOPS=0 + while [ "$LOOPS" -lt 5 ]; do + USER_UID="$(( 100000 + $RANDOM ))" + # check existence of this UID, if its free, use it + getent passwd "$USER_UID" || break + let LOOPS++ + done + if [ "$LOOPS" -eq 5 ]; then + # could not find an empty random 6-digit UID, so we will use demo's UID... + USER_UID="$(id -u demo)" + [ -z "$USER_UID" ] && echo "Could not use UID of 'demo' as a fallback, aborting..." && exit 1 + fi + + # we have a uid, gid, lets just create the local user now + if ! grep -q "^${PAM_USER}:" /etc/passwd; then + echo "${PAM_USER}:x:${USER_UID}:${USER_GID}:${PAM_USER}:/home/${PAM_USER}:/bin/bash" >> /etc/passwd + fi + exit 0 + elif [ "x$ret" != "x401" ]; then + # not 200, not 401, some other kind of error occured, inform slx-admin + echo "Unexpected http response code for the login attempt: $ret" + exit 7 + fi + exit 1 +fi + +if [ "x$PAM_TYPE" == "xaccount" ]; then + # the sanity checks we did before reacting to PAM_TYPE is enough to validate + # the given username as a valid bwIDM username + # ('@' contained and IdP found in the idp list fetched from the masterserver) + # so just "accept" + exit 0 +fi + +# script should never get to the following line +echo "$0 called for unsupported PAM_TYPE '$PAM_TYPE'. Aborting." +exit 1 +) +## main script +mainret=$? +if [ "x$mainret" == "x7" ]; then + # exit code 7 is our marker to push the logfile to the sat + slxlog --delete "pam-bwidm" "Internal error during bwIDM authentication" "${LOGFILE}" + exit 1 +else + rm -- "${LOGFILE}" +fi +exit "${mainret}" + diff --git a/core/modules/pam-bwidm/module.build b/core/modules/pam-bwidm/module.build new file mode 100644 index 00000000..62d96224 --- /dev/null +++ b/core/modules/pam-bwidm/module.build @@ -0,0 +1,11 @@ +fetch_source() { + : +} + +build() { + pinfo "Static module, nothing to build." +} + +post_copy() { + : +} diff --git a/core/modules/pam-bwidm/module.conf b/core/modules/pam-bwidm/module.conf new file mode 100644 index 00000000..4ae05d5a --- /dev/null +++ b/core/modules/pam-bwidm/module.conf @@ -0,0 +1,2 @@ +REQUIRED_BINARIES=" +" diff --git a/core/modules/pam-common-share/data/opt/openslx/scripts/pam_script_mount_common_share b/core/modules/pam-common-share/data/opt/openslx/scripts/pam_script_mount_common_share index 670943f4..d0bd8842 100644 --- a/core/modules/pam-common-share/data/opt/openslx/scripts/pam_script_mount_common_share +++ b/core/modules/pam-common-share/data/opt/openslx/scripts/pam_script_mount_common_share @@ -118,12 +118,13 @@ mount_share() { # check for failures if [ -e "${SIGNAL}" ]; then - slxlog "pam-share-mount" "Mount of '${SHARE_PATH}' to '${TARGET_DIR}' failed. (Args: ${MOUNT_OPTS}" "${MOUNT_OUTPUT}" - rm -f -- "${SIGNAL}" + slxlog --delete "pam-share-mount" "Mount of '${SHARE_PATH}' to '${TARGET_DIR}' failed. (Args: '${MOUNT_OPTS}')" "${MOUNT_OUTPUT}" + rm -f -- "${SIGNAL}" elif kill -9 "${MOUNT_PID}" 2>/dev/null; then - slxlog "pam-share-mount" "Mount of '${SHARE_PATH}' to '${TARGET_DIR}' timed out. (Args: ${MOUNT_OPTS}" "${MOUNT_OUTPUT}" + slxlog --delete "pam-share-mount" "Mount of '${SHARE_PATH}' to '${TARGET_DIR}' timed out. (Args: '${MOUNT_OPTS}')" "${MOUNT_OUTPUT}" + else + rm -f -- "${MOUNT_OUTPUT}" fi - ( sleep 2; rm -f -- "${MOUNT_OUTPUT}" ) & # always unset credentials unset USER diff --git a/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close b/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close index cd35a86b..e4a7c1b4 100755 --- a/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close +++ b/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close @@ -6,6 +6,8 @@ export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/o # can only work if script is run as root [ "x$(whoami)" = "xroot" ] || exit 0 +[ "x${PAM_SERVICE%greeter}" != "x${PAM_SERVICE}" ] && exit 0 + # NSA needs to know if [ "x$PAM_SERVICE" != "xsu" -a "x$PAM_SERVICE" != "xsudo" ]; then . /opt/openslx/config diff --git a/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_open b/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_open index 8ab34708..b918278e 100755 --- a/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_open +++ b/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_open @@ -3,6 +3,9 @@ # Needed as pam_script clears PATH export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin" +# just exit for greeter sessions +[ "x${PAM_SERVICE%greeter}" != "x${PAM_SERVICE}" ] && exit 0 + # NSA needs to know if [ "x$PAM_SERVICE" != "xsu" -a "x$PAM_SERVICE" != "xsudo" ]; then . /opt/openslx/config diff --git a/core/modules/pam/module.conf b/core/modules/pam/module.conf index 4e2e01a1..4fe76253 100644 --- a/core/modules/pam/module.conf +++ b/core/modules/pam/module.conf @@ -3,6 +3,7 @@ REQUIRED_BINARIES=" rpc.gssd rpc.idmapd sslconnect + unix_chkpwd " REQUIRED_LIBRARIES=" nsswitch diff --git a/core/modules/pam/module.conf.ubuntu b/core/modules/pam/module.conf.ubuntu index d675116c..7b2ceb50 100644 --- a/core/modules/pam/module.conf.ubuntu +++ b/core/modules/pam/module.conf.ubuntu @@ -9,8 +9,8 @@ REQUIRED_INSTALLED_PACKAGES=" libnfsidmap2 nfs-common libpam0g-dev - ncpfs cifs-utils + libpam-modules-bin " REQUIRED_CONTENT_PACKAGES=" libpam0g @@ -25,15 +25,11 @@ REQUIRED_CONTENT_PACKAGES=" ldap-utils libnfsidmap2 nfs-common - ncpfs cifs-utils + libpam-modules-bin " REQUIRED_BINARIES+=" nwmsg - ncpmount - ncpumount - mount.ncp - mount.ncpfs mount.cifs " REQUIRED_DIRECTORIES+=" diff --git a/core/modules/pam/module.conf.ubuntu.14 b/core/modules/pam/module.conf.ubuntu.14 index 64ead96a..455be684 100644 --- a/core/modules/pam/module.conf.ubuntu.14 +++ b/core/modules/pam/module.conf.ubuntu.14 @@ -1,4 +1,3 @@ -# TODO fix and re-add ncp support ! REQUIRED_INSTALLED_PACKAGES=" libpam-ldap libnss-ldapd @@ -11,6 +10,7 @@ REQUIRED_INSTALLED_PACKAGES=" nfs-common libpam0g-dev cifs-utils + libpam-modules-bin " REQUIRED_CONTENT_PACKAGES=" libpam0g @@ -26,6 +26,7 @@ REQUIRED_CONTENT_PACKAGES=" libnfsidmap2 nfs-common cifs-utils + libpam-modules-bin " REQUIRED_BINARIES+=" mount.cifs diff --git a/core/modules/printergui/data/opt/openslx/scripts/run-virt_print b/core/modules/printergui/data/opt/openslx/scripts/run-virt_print index ba352778..2f98b1ff 100755 --- a/core/modules/printergui/data/opt/openslx/scripts/run-virt_print +++ b/core/modules/printergui/data/opt/openslx/scripts/run-virt_print @@ -53,6 +53,12 @@ else errlog "printergui-nogs" "Warning: Cannot validate file prior to printing: gs binary not found" fi +# Set username prefix if found +. /opt/openslx/config +if [ -n "$SLX_PRINT_USER_PREFIX" ]; then + export PWGUI_USERPREFIX="$SLX_PRINT_USER_PREFIX" +fi + # Try to print $PRINTERGUI "$USER" "$FILE" RET=$? diff --git a/core/modules/printergui/module.build b/core/modules/printergui/module.build index a6f3ab17..3ede1dfc 100644 --- a/core/modules/printergui/module.build +++ b/core/modules/printergui/module.build @@ -1,15 +1,15 @@ #!/bin/bash fetch_source() { - git clone "${REQUIRED_GIT}" src - cd src + git clone "${REQUIRED_GIT}" "${MODULE_WORK_DIR}/src" + cd "{MODULE_WORK_DIR}/src" git checkout "$REQUIRED_COMMIT" - cd .. + cd - &>/dev/null } build() { local SRCDIR="${MODULE_WORK_DIR}/src/" - local DESTDIR="$MODULE_BUILD_DIR/opt/openslx/cups" + local DESTDIR="${MODULE_BUILD_DIR}/opt/openslx/cups" # first activate qt 4 activate_qt 4 diff --git a/core/modules/pvs2/data/etc/systemd/system/multi-user.target.wants/pvsmgr.service b/core/modules/pvs2/data/etc/systemd/system/multi-user.target.wants/pvsmgr.service new file mode 120000 index 00000000..cab88a66 --- /dev/null +++ b/core/modules/pvs2/data/etc/systemd/system/multi-user.target.wants/pvsmgr.service @@ -0,0 +1 @@ +../pvsmgr.service
\ No newline at end of file diff --git a/core/modules/pvs2/data/etc/systemd/system/pvsmgr.service b/core/modules/pvs2/data/etc/systemd/system/pvsmgr.service new file mode 100644 index 00000000..281e1ab4 --- /dev/null +++ b/core/modules/pvs2/data/etc/systemd/system/pvsmgr.service @@ -0,0 +1,12 @@ +[Unit] +Description=Fetch up to date pvsmgr config +DefaultDependencies=no +After=tmp.target +Wants=tmp.target +Before=graphical.target + +[Service] +Type=oneshot +ExecStart=/opt/openslx/scripts/systemd-pvsmgr +RemainAfterExit=yes + diff --git a/core/modules/pvs2/data/opt/openslx/bin/pvsstartup b/core/modules/pvs2/data/opt/openslx/bin/pvsstartup new file mode 100755 index 00000000..16a01708 --- /dev/null +++ b/core/modules/pvs2/data/opt/openslx/bin/pvsstartup @@ -0,0 +1,25 @@ +#!/bin/ash + +timediff=5 +counter=0 + +. /opt/openslx/config +EXAM= +if [ -n "$SLX_EXAM" ]; then + EXAM="--exam-mode" +fi + +while [ $timediff -gt 3 ]; do + start="$(date +%s)" + pvsclient $EXAM "$@" + ret=$? + end="$(date +%s)" + /opt/openslx/pvs2/kb-unlock.sh + [ "$ret" == "0" ] && break + timediff=$(( end - start )) + counter=$(( counter + 1 )) + [ $counter -gt 8 ] && break +done + +exit $ret + diff --git a/core/modules/pvs2/data/opt/openslx/iptables/rules.d/10-pvs b/core/modules/pvs2/data/opt/openslx/iptables/rules.d/10-pvs new file mode 100755 index 00000000..a24491fa --- /dev/null +++ b/core/modules/pvs2/data/opt/openslx/iptables/rules.d/10-pvs @@ -0,0 +1,11 @@ +#!/bin/ash + +# Allow PVS ports +# Control connection - server and client perspective +iptables -I ipt-helper-INPUT 1 -i br0 -p tcp --dport 5194 -j ACCEPT +iptables -I ipt-helper-OUTPUT 1 -o br0 -p tcp --dport 5194 -j ACCEPT +# UDP discovery - server and client perspective +iptables -I ipt-helper-INPUT 1 -i br0 -p udp --dport 3492 -j ACCEPT +iptables -I ipt-helper-OUTPUT 1 -o br0 -p udp --dport 3492 -j ACCEPT +# VNC connection - incoming (client) only - small range as we use -autoport +iptables -I ipt-helper-INPUT 1 -i br0 -p tcp --dport 54112:54122 -j ACCEPT diff --git a/core/modules/pvs2/data/opt/openslx/pvs2/lockDesktop.sh b/core/modules/pvs2/data/opt/openslx/pvs2/lockDesktop.sh new file mode 100755 index 00000000..c9cfc421 --- /dev/null +++ b/core/modules/pvs2/data/opt/openslx/pvs2/lockDesktop.sh @@ -0,0 +1,25 @@ +#!/bin/ash + +# Problem: While any application (e.g. VMware) is holding the mouse and +# keyboard grab, xscreensaver couldn't grab them, so it will ignore the +# locking request. Without the keyboard grab, all input would still go +# to the vmware window below the black screen, which is, you know, bad, +# since you cannot enter your password to unlock the workstation again. + +# So we minimize vmware, lock the screen, and then restore vmware. +# TODO: Add other virtualizers (vbox, kvm) later if needed. +WINDOWS=$(xdotool search --class vmplayer) +for window in $WINDOWS; do + xdotool windowminimize $window +done +# move mouse pointer to the center of the screen to avoid some problems with ghost clicks +xdotool mousemove --polar 0 0 --sync + +# now actually lock +xscreensaver-command --lock + +# above lock call is blocking, so now xscreensaver should be active - let's restore vmware +for window in $WINDOWS; do + xdotool windowmap $window +done + diff --git a/core/modules/pvs2/data/opt/openslx/scripts/setup-pvsmgr b/core/modules/pvs2/data/opt/openslx/scripts/setup-pvsmgr index dedb0995..5531518a 100755 --- a/core/modules/pvs2/data/opt/openslx/scripts/setup-pvsmgr +++ b/core/modules/pvs2/data/opt/openslx/scripts/setup-pvsmgr @@ -1,4 +1,30 @@ #!/bin/ash +. /opt/openslx/config + +# Try to get fresh version from server +CONF= +if [ -n "$SLX_PVS_CONFIG_URL" ]; then + DST="$(mktemp)" + wget -T 5 -O "${DST}" "$SLX_PVS_CONFIG_URL" + [ -s "${DST}" ] && CONF="--config=${DST}" +fi + openbox & -exec /opt/openslx/bin/pvsmgr + +timediff=5 +counter=0 + +while [ $timediff -gt 3 ]; do + start="$(date +%s)" + /opt/openslx/bin/pvsmgr "$CONF" "$@" + ret=$? + [ "$ret" == "0" ] && break + end="$(date +%s)" + timediff=$(( end - start )) + counter=$(( counter + 1 )) + [ $counter -gt 8 ] && break +done + +exit $ret + diff --git a/core/modules/pvs2/data/opt/openslx/scripts/systemd-pvsmgr b/core/modules/pvs2/data/opt/openslx/scripts/systemd-pvsmgr new file mode 100755 index 00000000..1a56e8d0 --- /dev/null +++ b/core/modules/pvs2/data/opt/openslx/scripts/systemd-pvsmgr @@ -0,0 +1,22 @@ +#!/bin/ash + +. /opt/openslx/config +DST="/opt/openslx/pvs2/pvs2.ini" + +# Try to get fresh version from server +if [ -n "$SLX_PVS_CONFIG_URL" ]; then + wget -T 10 -O "${DST}.new" "$SLX_PVS_CONFIG_URL" + [ -s "${DST}.new" ] && mv -f "${DST}.new" "${DST}" +fi + +# If this is a dedicated PVS station, make it launch right away +if [ -n "$SLX_PVS_DEDICATED" ] && cd /opt/openslx/xsessions; then + for file in *.desktop; do + cp -f "/usr/share/xsessions/pvs2mgr.desktop" "$file" + done + # patch autologin into kdmrc + sed -i '/AutoLogin.*=/d;/^\[X-.*-Core\]/a AutoLoginEnable=true\nAutoLoginUser=demo\nAutoLoginAgain=true\nAutoLoginDelay=0' "/etc/kde/kdm/kdmrc" +fi + +exit 0 + diff --git a/core/modules/pvs2/data/opt/openslx/vmchooser/sessionstart.d/50-PVSclient b/core/modules/pvs2/data/opt/openslx/vmchooser/sessionstart.d/50-PVSclient index 0ad739e0..5ff03227 100755 --- a/core/modules/pvs2/data/opt/openslx/vmchooser/sessionstart.d/50-PVSclient +++ b/core/modules/pvs2/data/opt/openslx/vmchooser/sessionstart.d/50-PVSclient @@ -1,6 +1,6 @@ #!/bin/ash -# SESSION_TYPE can be either 'VSESSION' or 'XSESSION' - currently not evaluated +# SESSION_TYPE can be either 'VSESSION' or 'XSESSION' # detect session command of the PVS-Manager session by looking at the xsession file PVSMGR_SESSION_CMD= @@ -17,10 +17,43 @@ if [ -n "${PVSMGR_SESSION_CMD}" ]; then # do not start pvsclient if we are running the pvs manager session [ "x${SESSION_CMD}" == "x${PVSMGR_SESSION_CMD}" ] && exit 0 fi + +# Download fresh copy of config file if possible +. /opt/openslx/config +PVSCONFIG= +if [ -n "$SLX_PVS_CONFIG_URL" ]; then + [ -z "$UID" ] && UID="$(id -u)" + [ -z "$HOME" ] && HOME="$(getent passwd "$UID" | head -n 1 | awk -F ':' '{print $6}')" + mkdir -p "$HOME/.tmp" + if wget -T 5 -O "$HOME/.tmp/pvs2.ini.tmp" "$SLX_PVS_CONFIG_URL"; then + mv -f "$HOME/.tmp/pvs2.ini.tmp" "$HOME/.tmp/pvs2.ini" + fi + if ! [ -s "$HOME/.tmp/pvs2.ini" ] && [ -s "/opt/openslx/pvs2/pvs2.ini" ]; then + cp -f "/opt/openslx/pvs2/pvs2.ini" "$HOME/.tmp/pvs2.ini" + fi + if [ -s "$HOME/.tmp/pvs2.ini" ]; then + PVSCONFIG="--config=$HOME/.tmp/pvs2.ini" + fi +fi + # If the ENV var PVS has been set by vmchooser start pvsclient -if [ -n "$PVS_AUTO_CONNECT" -a "$PVS_AUTO_CONNECT" == "TRUE" ]; then - pvsclient --auto & +if [ "$PVS_AUTO_CONNECT" == "TRUE" ]; then + pvsstartup "$PVSCONFIG" --auto & else - pvsclient & + pvsstartup "$PVSCONFIG" & fi + +# Finally, handle hybrid mode where the pvsmgr is launched on the second desktop +# alongside the actual vm. (make sure this is a VSESSION!) +if [ "$SESSION_TYPE" == "VSESSION" ]; then + { + wt="PVS2-Manager" + pvsmgr "$PVSCONFIG" --manager-only & + for i in 100 100 200 200 200 300 500 500 1000; do + usleep $(( i * 1000 )) || sleep 1 + wmctrl -r "$wt" -t 1 + done + } & +fi + exit 0 diff --git a/core/modules/pvs2/module.build b/core/modules/pvs2/module.build index b7ccfa47..f356e1bc 100644 --- a/core/modules/pvs2/module.build +++ b/core/modules/pvs2/module.build @@ -1,28 +1,37 @@ #!/bin/bash fetch_source() { - git clone "${REQUIRED_GIT}" src + git clone "${REQUIRED_GIT}" "${MODULE_WORK_DIR}/src" } build() { - local SRCDIR="${MODULE_WORK_DIR}/src/" - local BUILDDIR="$SRCDIR/build/" - local DESTDIR="$MODULE_BUILD_DIR/opt/openslx/bin" + local BUILDDIR="${SRCDIR}/build/" + local DESTDIR="${MODULE_BUILD_DIR}/opt/openslx/bin" # first activate qt 4 activate_qt 4 - mkdir -p "$DESTDIR" || perror "Could not mkdir $DESTDIR!" - mkdir -p "$BUILDDIR" || perror "Could not mkdir $BUILDDIR!" - cd "$BUILDDIR" || perror "Could not cd to $BUILDDIR!" + mkdir -p "${DESTDIR}" || perror "Could not mkdir ${DESTDIR}!" + mkdir -p "${BUILDDIR}" || perror "Could not mkdir ${BUILDDIR}!" + cd "${BUILDDIR}" || perror "Could not cd to ${BUILDDIR}!" pinfo "Running cmake" cmake .. || perror "'cmake ..' failed." pinfo "Running make" make || perror "'make' failed." - mv pvsmgr pvsclient $DESTDIR - cd - > /dev/null + mv pvsmgr pvsclient "${DESTDIR}" + cd .. + + # copy external scripts under 'sample_configuration' + mkdir -p "${MODULE_BUILD_DIR}/opt/openslx/pvs2/" + if [ -d "${SRCDIR}/sample_configuration" ]; then + # Do not copy lockDesktop.sh - we ship a modified one + cp "${SRCDIR}/sample_configuration"/{kb-lock,kb-unlock,switchToManager,switchBack}.sh "${MODULE_BUILD_DIR}/opt/openslx/pvs2/" \ + || perror "Could not copy external scripts to '${MODULE_BUILD_DIR}/opt/openslx/pvs2/'!" + chmod +x "${MODULE_BUILD_DIR}/opt/openslx/pvs2"/*.sh \ + || perror "Could not set executable bit for external scripts." + fi # needed for copying REQUIRED_CONTENT_PACKAGES to build/ COPYLIST="list_dpkg_output" diff --git a/core/modules/pvs2/module.conf b/core/modules/pvs2/module.conf index 9ef50afd..5e7a9a6f 100644 --- a/core/modules/pvs2/module.conf +++ b/core/modules/pvs2/module.conf @@ -2,6 +2,12 @@ REQUIRED_GIT="git://git.openslx.org/pvs2.git" REQUIRED_BINARIES=" pvsmgr pvsclient + xinput + wmctrl +" +REQUIRED_DIRECTORIES=" + /opt/openslx/pvs2/ + /usr/lib/ " REQUIRED_LIBRARIES=" " diff --git a/core/modules/pvs2/module.conf.ubuntu b/core/modules/pvs2/module.conf.ubuntu index 4dcf2794..8a48ec93 100644 --- a/core/modules/pvs2/module.conf.ubuntu +++ b/core/modules/pvs2/module.conf.ubuntu @@ -1,11 +1,12 @@ REQUIRED_INSTALLED_PACKAGES=" libqt4-dev libvncserver-dev + xinput + wmctrl " REQUIRED_CONTENT_PACKAGES=" libqt4-svg libqtgui4 -" -REQUIRED_DIRECTORIES=" - /usr/lib/ + xinput + wmctrl " diff --git a/core/modules/qemukvm/FIXME b/core/modules/qemukvm/FIXME new file mode 100644 index 00000000..a3523e53 --- /dev/null +++ b/core/modules/qemukvm/FIXME @@ -0,0 +1 @@ +This module was never finished. It should not be used as is. diff --git a/core/modules/qemukvm/data/opt/openslx/vmchooser/qemukvm/run-virt.include b/core/modules/qemukvm/data/opt/openslx/vmchooser/qemukvm/run-virt.include index 29360159..81bf9218 100644 --- a/core/modules/qemukvm/data/opt/openslx/vmchooser/qemukvm/run-virt.include +++ b/core/modules/qemukvm/data/opt/openslx/vmchooser/qemukvm/run-virt.include @@ -44,16 +44,16 @@ mkdir -m 1777 -p ${QKTMPDIR} 2>/dev/null diskfile=${vmpath} # check the file type -if echo ${imgname} | grep -iE "img|qcow|vmdk" >/dev/null 2>&1; then - imgtype=$(echo ${imgname##*.} | tr "[a-z]" "[A-Z]") +if echo ${IMG_BASENAME} | grep -iE "img|qcow|vmdk" >/dev/null 2>&1; then + imgtype=$(echo ${IMG_BASENAME##*.} | tr "[a-z]" "[A-Z]") else - writelog "${imgname} is not a valid image type (img|qcow*|vmdk), exiting!" + writelog "${IMG_BASENAME} is not a valid image type (img|qcow*|vmdk), exiting!" exit 1 fi # set the emulator/virtualization options for various operating systems sound="es1370" -case "${vmostype}" in +case "${VM_OS_TYPE}" in beos*) VIRTCMDOPTS="qemu-system-i386 -machine accel=tcg" sound="sb16" @@ -91,8 +91,8 @@ esac #VIRTCMDOPTS="${VIRTCMDOPTS} -alt-grab" # display name, remove blanks because of cmdline problems -displayname=$(echo ${displayname} | sed -e "s, ,-,g;s,(,[,g;s,),],g") -VIRTCMDOPTS="${VIRTCMDOPTS} -name ${displayname}" +VM_DISPLAYNAME=$(echo ${VM_DISPLAYNAME} | sed -e "s, ,-,g;s,(,[,g;s,),],g") +VIRTCMDOPTS="${VIRTCMDOPTS} -name ${VM_DISPLAYNAME}" writelog "Directories:" writelog "\tTMPDIR:\t\t\t$QKTMPDIR" diff --git a/core/modules/qemukvm/module.conf.ubuntu b/core/modules/qemukvm/module.conf.ubuntu index d0fdc5f3..af29b8ad 100644 --- a/core/modules/qemukvm/module.conf.ubuntu +++ b/core/modules/qemukvm/module.conf.ubuntu @@ -1,26 +1,27 @@ REQUIRED_INSTALLED_PACKAGES=" qemu qemu-kvm + vgabios " REQUIRED_CONTENT_PACKAGES=" qemu qemu-kvm - ipxe-qemu - qemu-keymaps - qemu-system - qemu-system-arm - qemu-system-common - qemu-system-mips - qemu-system-misc - qemu-system-ppc - qemu-system-sparc - qemu-system-x86 - qemu-user + ipxe-qemu + qemu-keymaps + qemu-system + qemu-system-arm + qemu-system-common + qemu-system-mips + qemu-system-misc + qemu-system-ppc + qemu-system-sparc + qemu-system-x86 + qemu-user qemu-utils seabios vgabios - cpu-checker + cpu-checker kvm-ipxe libaio1 libboost-thread1.49.0 diff --git a/core/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials b/core/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials new file mode 100644 index 00000000..a03d8886 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials @@ -0,0 +1,41 @@ +#!/bin/ash +# This is being sourced and running in ash + +if [ -n "$TEMP_HOME_DIR" ]; then + if [ -z "$PAM_TTY" ] || [ "x$PAM_TTY" = "x:0" ]; then + # Pass on network path to home directory + if [ -z "$PERSISTENT_NETPATH" ]; then + PERSISTENT_NETPATH=$(grep -m1 -F " ${PERSISTENT_HOME_DIR} " "/proc/mounts" | awk '{print $1}') + fi + if [ -n "$PERSISTENT_NETPATH" ]; then + [ "x${PERSISTENT_NETPATH:0:2}" = "x//" ] && PERSISTENT_NETPATH=$(echo "$PERSISTENT_NETPATH" | tr '/' '\') + echo "${PERSISTENT_NETPATH}" > "${TEMP_HOME_DIR}/.home" + chmod 0644 "${TEMP_HOME_DIR}/.home" + fi + # pwdaemon + # Figure out username + XUSER="${REAL_ACCOUNT}" + [ -z "$XUSER" ] && XUSER="${PAM_USER}" + # Guess domain + XDOMAIN= + if [ -n "$PERSISTENT_HOME_DIR" ]; then + XDOMAIN=$(grep -F " ${PERSISTENT_HOME_DIR} " "/proc/mounts" | grep -m1 -F 'domain=' | sed -r 's/^.*[ ,]domain=([^ ,]+)[ ,].*$/\1/g') + fi + if [ -z "$XDOMAIN" ]; then + XDOMAIN=$(grep -m1 -i '^BASE\s*DC=' "/etc/ldap.conf" | sed -r 's/^BASE\s*DC=([^,;]+).*$/\1/I') + fi + if [ -z "$XDOMAIN" ]; then + XDOMAIN=$(grep -m1 -i '^ldap_search_base\s*=\s*DC=' "/etc/sssd/sssd.conf" | sed -r 's/^ldap_search_base\s*=\s*DC=([^,;]+).*$/\1/I') + fi + if [ -n "$XDOMAIN" ]; then + XDOMAIN=$(echo "$XDOMAIN" | tr '[a-z]' '[A-Z]') + else + XDOMAIN="WORKGROUP" + fi + USERNAME="$XDOMAIN\\$XUSER" PASSWORD="$PAM_AUTHTOK" PWSOCKET="${TEMP_HOME_DIR}/.pwsocket" su -c 'pwdaemon --daemon &' "${PAM_USER}" & + unset XUSER XDOMAIN + fi +fi + +true + diff --git a/core/modules/run-virt/data/opt/openslx/scripts/pam_script_ses_close.d/runvirt-firewall-clear b/core/modules/run-virt/data/opt/openslx/scripts/pam_script_ses_close.d/runvirt-firewall-clear new file mode 100644 index 00000000..dab08190 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/scripts/pam_script_ses_close.d/runvirt-firewall-clear @@ -0,0 +1,17 @@ +#!/bin/ash + +# Sourced by pam_script_ses_close + +runvirt_fw_clear () { + iptables -w -F runvirt-INPUT + ip6tables -w -F runvirt-INPUT + iptables -w -F runvirt-OUTPUT + ip6tables -w -F runvirt-OUTPUT +} + +if [ "x$PAM_TTY" = "x:0" ]; then + runvirt_fw_clear > /dev/null 2>&1 +fi + +true + diff --git a/core/modules/run-virt/data/opt/openslx/scripts/systemd-mount_vm_store b/core/modules/run-virt/data/opt/openslx/scripts/systemd-mount_vm_store index 9d478918..235cf4be 100755 --- a/core/modules/run-virt/data/opt/openslx/scripts/systemd-mount_vm_store +++ b/core/modules/run-virt/data/opt/openslx/scripts/systemd-mount_vm_store @@ -13,8 +13,12 @@ OUTFILE=$(mktemp) # no bash, so this is a bit ugly... if [ "${SLX_VM_NFS#//}" = "${SLX_VM_NFS}" ]; then # doesn't start with '//' -> assume NFS - /opt/openslx/bin/timeout -t 10 -s 9 mount -v -t nfs -o ro,async,nolock "$SLX_VM_NFS" /mnt/vmstore + /opt/openslx/bin/timeout -t 6 -s 9 mount -v -t nfs -o ro,async,nolock "$SLX_VM_NFS" /mnt/vmstore RET=$? + if [ "$RET" != "0" ]; then + /opt/openslx/bin/timeout -t 6 -s 9 mount -v -t nfs -o vers=3,ro,async,nolock "$SLX_VM_NFS" /mnt/vmstore + RET=$? + fi else # starts with '//' -> assume CIFS export USER="$SLX_VM_NFS_USER" @@ -25,15 +29,14 @@ else RET=$? fi > "$OUTFILE" 2>&1 -if [ $RET -ne 0 ]; then +if [ "$RET" -ne "0" ]; then if [ -s "$OUTFILE" ]; then - slxlog "mount-vmstore-fail" "Mounting '$SLX_VM_NFS' failed. VMs will not boot." "$OUTFILE" - sleep 1 + slxlog --delete "mount-vmstore-fail" "Mounting '$SLX_VM_NFS' failed. VMs will not boot." "$OUTFILE" else slxlog "mount-vmstore-fail" "Mounting '$SLX_VM_NFS' failed. VMs will not boot." + rm -f -- "$OUTFILE" fi fi -rm -f -- "$OUTFILE" exit $RET diff --git a/core/modules/run-virt/data/opt/openslx/scripts/systemd-run_virt_env b/core/modules/run-virt/data/opt/openslx/scripts/systemd-run_virt_env index b8236600..a86b2d0b 100755 --- a/core/modules/run-virt/data/opt/openslx/scripts/systemd-run_virt_env +++ b/core/modules/run-virt/data/opt/openslx/scripts/systemd-run_virt_env @@ -28,27 +28,7 @@ export PATH=$PATH:/opt/openslx/bin:/opt/openslx/sbin # from plugins/vmchooser/XX_vmchooser.sh VMCHOOSER_DIR="/opt/openslx/vmchooser" VMCHOOSER_CONF_DIR="$VMCHOOSER_DIR/config" - -mkdir -p "${VMCHOOSER_DIR}/data/loopimg" -mkdir -p "${VMCHOOSER_DIR}/fd-loop" -m 1777 - -# mount a clean tempfs (bug in UnionFS prevents loopmount to work) -grep -qE "unionfs |aufs " /proc/mounts && \ - mount -n -o size=1500k -t tmpfs vm-loopimg "${VMCHOOSER_DIR}/data/loopimg" - -# create an empty floppy image of 1.44 MByte size -dd "if=/dev/zero" "of=${VMCHOOSER_DIR}/data/loopimg/fd.img" count=2880 bs=512 2>/dev/null -chmod 0777 "${VMCHOOSER_DIR}/data/loopimg/fd.img" - -# use dos formatter copied into stage3 -mkdosfs "${VMCHOOSER_DIR}/data/loopimg/fd.img" -mount -n -t msdos -o loop,umask=000 "${VMCHOOSER_DIR}/data/loopimg/fd.img" "${VMCHOOSER_DIR}/fd-loop" - -#pvs integration -#if [ $vmchooser_pvs -ne 0 ]; then -# sed -i /usr/share/xsessions/default.desktop \ -# -e "s,vmchooser$,vmchooser --pvs," -#fi +DHCP_NAT_CONF="/opt/openslx/vmchooser/config/udhcpd-nat1.conf" # setup more scratch space for virtual machines, if configured mkdir -p /tmp/virt /var/log/samba /run/samba @@ -110,10 +90,20 @@ fi # write mac if [ -n "$SLX_PXE_MAC" ]; then - echo "hostmacaddr=${SLX_PXE_MAC}" >> "${VMCHOOSER_CONF_DIR}/virtualization.conf" + hostmacaddr="${SLX_PXE_MAC}" else ## Fallback: - echo "hostmacaddr=$(ip a | grep ether | grep -o -E -i '([0-9a-f]{2}:){5}[0-9a-f]{2}' | head -n 1)" >> "${VMCHOOSER_CONF_DIR}/virtualization.conf" + hostmacaddr="$(ip a | grep ether | grep -o -E -i '([0-9a-f]{2}:){5}[0-9a-f]{2}' | head -n 1)" fi +echo "hostmacaddr='$hostmacaddr'" >> "${VMCHOOSER_CONF_DIR}/virtualization.conf" +# TODO: We should only generate the suffix here (last 3 octets) as the first 3 are +# dependant on the virtualizer/emulator. Check if any run-virt.include still relies on +# $macguestpart/$macaddr. If so, fix it to use its specific first 3 bytes +# and append $macaddrssuffix +macaddrprefix='00:50:56' +macaddrsuffix="$(echo "$hostmacaddr" | awk -F ":" '{print "%VMID%:" $(NF-1) ":" $NF}' | tr '[a-z]' '[A-Z]')" +echo "macaddrprefix='$macaddrprefix'" >> "${VMCHOOSER_CONF_DIR}/virtualization.conf" +echo "macaddrsuffix='$macaddrsuffix'" >> "${VMCHOOSER_CONF_DIR}/virtualization.conf" + # read in ip address echo "hostip=${SLX_PXE_CLIENT_IP}" >> "${VMCHOOSER_CONF_DIR}/virtualization.conf" # hostname @@ -132,6 +122,11 @@ for floppy in $(dmesg|grep -i "Floppy drive"|sed "s,.*(s): ,,;s, is .*,,"); do j=$(expr $j + 1) done +# Serial ports +echo "serial_ports='$(dmesg | grep -Eo 'ttyS[0-9]+' | sed 's,^,/dev/,' | tr '\n' ' ')'" >> "${VMCHOOSER_CONF_DIR}/virtualization.conf" +# Parallel ports +modprobe parport_pc + ################################################################################ ### Setup VM networking ################################################################################ @@ -163,19 +158,27 @@ echo "1" >/proc/sys/net/ipv4/conf/br0/forwarding 2>/dev/null ### iptables -t nat -A POSTROUTING -o br0 -s 192.168.0.0/16 -j MASQUERADE for wait in 1 1 2 2 3 end; do - grep '^SLX_DNS' "/opt/openslx/config" > /dev/null && break - [ "$wait" == "end" ] && echo "No DNS config found, using google dns" && break - echo "Waiting for DNS config.." + [ -n "$SLX_DNS" ] && [ -n "$SLX_NET_SEARCH" ] && break + if [ "$wait" == "end" ]; then + echo "No DNS config found, using google dns" + break + fi + echo "Waiting for DNS & search-domain config.." sleep "$wait" + . /opt/openslx/config done # read the DNS configuration and configure the udhcpd -[ -z "${SLX_DNS}" ] && SLX_DNS="8.8.8.8" -sed -i "s,DNSSERVER,${SLX_DNS},;s,DOMAIN,${SLX_NET_DOMAIN}," \ - /opt/openslx/vmchooser/config/udhcpd-nat1.conf +[ -z "${SLX_DNS}" ] && SLX_DNS="8.8.8.8 8.8.4.4" +[ -z "${SLX_NET_DOMAIN}" ] && SLX_NET_DOMAIN="virtual.site" +[ -z "${SLX_NET_SEARCH}" ] && SLX_NET_SEARCH="virtual.site" +sed -i "s#%DNSSERVER%#${SLX_DNS}#;s#%DOMAIN%#${SLX_NET_DOMAIN}#;s#%SEARCH%#${SLX_NET_SEARCH}#" "${DHCP_NAT_CONF}" + +# Make sure the primary vm running (we most likely never run more than one at a time anyways) always gets the same ip +echo "static_lease $(echo "$macaddrprefix:$macaddrsuffix" | sed 's/%VMID%/01/') 192.168.101.20" >> "${DHCP_NAT_CONF}" mkdir -p /var/lib/udhcpd -udhcpd -S /opt/openslx/vmchooser/config/udhcpd-nat1.conf +udhcpd -S "${DHCP_NAT_CONF}" # creating and configuring vsw2 brctl addbr vsw2 diff --git a/core/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt b/core/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt index 1e591389..447f98bc 100755..120000 --- a/core/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt +++ b/core/modules/run-virt/data/opt/openslx/scripts/vmchooser-run_virt @@ -1,116 +1 @@ -#!/bin/bash -# Full bash required -# ----------------------------------------------------------------------------- -# Copyright (c) 2007..2010 - RZ Uni FR -# Copyright (c) 2007..2013 - OpenSLX GmbH -# -# This program is free software distributed under the GPL version 2. -# See http://openslx.org/COPYING -# -# If you have any feedback please consult http://openslx.org/feedback and -# send your suggestions, praise, or complaints to feedback@openslx.org -# -# General information about OpenSLX can be found at http://openslx.org/ -# ----------------------------------------------------------------------------- -# run-virt.sh -# - This is the generic wrapper for the several virtualization solutions. -# The idea is to setup a set of variables used by at least two different -# tools and then include the specific plugin which configures the speci- -# fied virtualization tool. -################################################################################ - -RUNVIRTINCLUDEDIR=/opt/openslx/scripts/includes -xmlfile="$1" - -# Functions needed by vmchooser-run_virt (writelog(), cleanexit(), rv_clean_string()) -source ${RUNVIRTINCLUDEDIR}/vmchooser_runvirt_functions.inc && trap 'trap "" SIGINT SIGTERM; cleanexit' SIGINT SIGTERM -# Define default dirs / get configs -source ${RUNVIRTINCLUDEDIR}/set_runvirt_variables.inc -# Function to detect whether we can use the new way (vmx via http) or the old way (legacy): -source ${RUNVIRTINCLUDEDIR}/detect_legacy.inc # This yields LEGACY, IMGUUID, IMGVMX -# For scanning for certain usb classes -source "${RUNVIRTINCLUDEDIR}/usb_detector.inc" - -if [ "$LEGACY" ]; then - # check for important files used (filecheck()) - vestigial? - source ${RUNVIRTINCLUDEDIR}/check_runvirt_needed_files.inc - # Get XML file and dir, legacy (old way) - source ${RUNVIRTINCLUDEDIR}/get_xml_file_dir_legacy.inc # xmlfile=$1 - # xml file sanity checks, legacy - source ${RUNVIRTINCLUDEDIR}/check_runvirt_xml_sanity_legacy.inc - # print console logo - source ${RUNVIRTINCLUDEDIR}/print_runvirt_console_logo.inc - # Read needed variables from XML file - source ${RUNVIRTINCLUDEDIR}/get_xml_file_variables_legacy.inc - # Declaration of hardware relatedt variables - source ${RUNVIRTINCLUDEDIR}/set_runvirt_hardware_variables_legacy.inc - # Sound setup the rest of the environment and run the configured vm - source ${RUNVIRTINCLUDEDIR}/setup_sound.inc - # Start printer daemon - source ${RUNVIRTINCLUDEDIR}/setup_printer_lpd.inc - # Setup virtual floppy b: for windows guests with config.xml, openslx.exe etc. - source ${RUNVIRTINCLUDEDIR}/setup_virtual_floppy.inc - # Try to use dnbd3 to access the image, nfs/cifs fallback - source ${RUNVIRTINCLUDEDIR}/setup_image_access.inc - # Get all virtual machine specific stuff from the respective include file - source ${RUNVIRTINCLUDEDIR}/setup_vm_hypervisor.inc - # start a windowmanager for easier handling - source ${RUNVIRTINCLUDEDIR}/start_windowmanager.inc - # Start poolvideoswitch if DO_PROFILE has been set (WARNING: fixed IP!) - source ${RUNVIRTINCLUDEDIR}/start_pvs.inc - # Check if tcpsvd is running. Do not check immediately after spawning, - # as this could result in success even if it's not really working. - source ${RUNVIRTINCLUDEDIR}/check_lpd.inc -else - # check for important files used (filecheck()) - vestigial? - # This include does not currently work. TODO. - # source ${RUNVIRTINCLUDEDIR}/check_runvirt_needed_files.inc && filecheck - - # Read needed variables from XML file - source ${RUNVIRTINCLUDEDIR}/get_xml_file_variables.inc - - # Sound setup the rest of the environment and run the configured vm - source ${RUNVIRTINCLUDEDIR}/setup_sound.inc - - # Declaration of hardware relatedt variables - source ${RUNVIRTINCLUDEDIR}/set_runvirt_hardware_variables.inc - - # Start printer daemon - source ${RUNVIRTINCLUDEDIR}/setup_printer_lpd.inc - - # Setup virtual floppy b: for windows guests with config.xml, openslx.exe etc. - source ${RUNVIRTINCLUDEDIR}/setup_virtual_floppy.inc - - # Get all virtual machine specific stuff from the respective include file - source ${RUNVIRTINCLUDEDIR}/setup_image_access.inc - - # start a windowmanager for easier handling - source ${RUNVIRTINCLUDEDIR}/setup_vm_hypervisor.inc - - # Try to use dnbd3 to access the image, nfs/cifs fallback - source ${RUNVIRTINCLUDEDIR}/start_windowmanager.inc - - # Start poolvideoswitch if DO_PROFILE has been set (WARNING: fixed IP!) - source ${RUNVIRTINCLUDEDIR}/start_pvs.inc - - # Check if tcpsvd is running. Do not check immediately after spawning, - # as this could result in success even if it's not really working. - source ${RUNVIRTINCLUDEDIR}/check_lpd.inc - -fi - -# This will start the VM -writelog "VM command: eval ${VIRTCMD} ${VIRTCMDOPTS}" - -# Transported from vmware-runvirt include -sync - -eval ${VIRTCMD} ${VIRTCMDOPTS} -writelog "Bye." - -# Postrun for commands after virtualization finishes -if [ -n "${POSTRUN}" ]; then - eval ${POSTRUN} >/dev/null 2>&1 -fi - -cleanexit 0 +/opt/openslx/vmchooser/vmchooser-run_virt
\ No newline at end of file diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/config/udhcpd-nat1.conf b/core/modules/run-virt/data/opt/openslx/vmchooser/config/udhcpd-nat1.conf index bca1397c..95d8ebc0 100644 --- a/core/modules/run-virt/data/opt/openslx/vmchooser/config/udhcpd-nat1.conf +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/config/udhcpd-nat1.conf @@ -31,11 +31,12 @@ lease_file /var/lib/udhcpd/udhcpd-nat1.leases # location of the pid file pidfile /var/run/udhcpd-nat1.pid -option dns DNSSERVER +option dns %DNSSERVER% option subnet 255.255.255.0 option router 192.168.101.1 option wins 192.168.101.10 -option domain DOMAIN virtual.site +option domain %DOMAIN% +option search %SEARCH% option lprsrv 192.168.101.1 #option ntpsrv NTPSERVER diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/LIESMICH b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/LIESMICH new file mode 100644 index 00000000..326af2a4 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/LIESMICH @@ -0,0 +1,24 @@ +Dieses Paket besteht aus folgenden Skripten: + +vm_installer: Dieses Skript einmalig in einer lokalen, permanenten (also + nicht innerhalb des Poolsystems) Virtuellen Maschine ausführen. + Es schreibt eine systemd-Servicedatei und verlinkt diese, um + beim Systemstart per vm_runtime die Skripte zu Auflösungsan- + passung und Einhängung eventuell übergebener Netzlaufwerke + nach Hochladung der VM in das Poolsystem automatisch zu starten. + Das Skript kann von der gemounteten (Pseudo-)Diskette /dev/fd1 + aus oder einzelstehend gestartet werden. + Unterstützung für init-basierte Systeme folgt noch. +vm_runtime: Dieses Skript wird beim booten der VM aufgerufen und patcht + Xsetup, um beim grafischen Start der VM die Skripte shares + und resolution aufzurufen. +mnt_shares: Liest die auf Pseudodiskette gegebene shares.dat aus und hängt + ggf. darin angegebene Netzlaufwerke ein. +resolution: Stellt die Auflösung der VM anhand der übergebenen Auflösung + des Grundsystems ein. + +resolution_standalone: Einzelstehende Version des resolution-Skriptes, die + keine Vorarbeiten seitens systemd bzw. vm_runtime benötigt. + Für geeignete Einbindung innerhalb der VM muss daher selbst + gesorgt werden. + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/README b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/README new file mode 100644 index 00000000..12777c67 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/README @@ -0,0 +1,21 @@ +This package consists of the following scripts: + +vm_installer: This script is to be started once in a local, permanent (so + not within the pool system environment) virtual machine. It + writes a systemd service file and links it, so the scripts + for resolution setting and mounting network shares will be + started at boot time at boot time via vm_runtime. + It may be run from the mounted (pseudo) disk drive /dev/fd1 + or from elsewhere. + init will be supported at later time. +vm_runtime: Will be started at boot time and patches Xsetup, so the + scripts mnt_shares and resolution will be started at graphical + login. +mnt_shares: Reads the config file shares.dat from (pseudo) disk drive and + mounts therein given network shares. +resolution: Sets resolution within the virtual machine according to base + system resolution given via config file openslx.ini. + +resolution_standalone: Standalone version of resolution sctipt. Needs no + preliminary work done by systemd or vm_runtime. + One has to embed/start it via adequate means by hand. diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/00_vars.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/00_vars.inc new file mode 100644 index 00000000..bb7ae3a1 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/00_vars.inc @@ -0,0 +1,29 @@ +### Variablen ##################################### +LOCALUSER=student +USERHOME=/home/"$LOCALUSER" +USERHOMEDIR=/home/"$LOCALUSER"/PERSISTENT +DISKMOUNTDIR=/mnt/diskmount +SLXCONFIGFILE="$DISKMOUNTDIR"/openslx.ini +CONFIGFILE="$DISKMOUNTDIR"/shares.dat +KEYTEMP=$(mktemp -t XXXXXXXXXX.dat) +RAWKEYTEMP=$(mktemp -t XXXXXXXXXX.dat) +BYTES=256 +declare -a ROHSHARES + +if [ ! $(mount 2>/dev/null | grep -q "$DISKMOUNTDIR") ]; then + [ ! -d "$DISKMOUNTDIR" ] && mkdir -p "$DISKMOUNTDIR" + mount /dev/fd1 "$DISKMOUNTDIR" 2>/dev/null 1>&2 # Zu erl.: Fehlerfangen +fi + +NATADDR=$(head -n 1 "$CONFIGFILE" | cut -f 1 -d$'\t') +PORT=$(head -n 1 "$CONFIGFILE" | cut -f 2 -d$'\t') +SCHLUESSEL=$(head -n 1 "$CONFIGFILE" | cut -f 4 -d$'\t') +GLOBALDOMAINUSER=$(head -n 1 "$CONFIGFILE" | cut -f 5 -d$'\t') +GLOBALUSER=$(echo "$GLOBALDOMAINUSER" | cut -d '\' -f 2) + +REMAPMODE=$(grep 'remapMode=' "$SLXCONFIGFILE" | cut -d '=' -f 2) +CREATEMISSING=$(grep 'createMissingRemap=' "$SLXCONFIGFILE" | cut -d '=' -f 2) + +MOUNTOPTSCIFS="-v -t cifs -o uid=$(id --user "$LOCALUSER"),gid=$(id --group "$LOCALUSER"),forceuid,forcegid,file_mode=0700,dir_mode=0700,nobrl,noacl" +MOUNTOPTSNFS="-v -t nfs4 -o rw,nosuid,nodev,nolock,intr,hard,sloppy" +### Variablen Ende ################################ diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/10_functions.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/10_functions.inc new file mode 100644 index 00000000..97767c51 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/10_functions.inc @@ -0,0 +1,51 @@ +### Funktionen #################################### + +function xor() +{ local RES=($(echo "$1" | sed "s/../0x& /g")) + shift 1 + while [[ "$1" ]]; do + local ONE=($(echo "$1" | sed "s/../0x& /g")) + local COUNT1=${#RES[@]} + if [ $COUNT1 -lt ${#ONE[@]} ]; then + COUNT1=${#ONE[@]} + fi + for (( i = 0; i < $COUNT1; i++ )); do + RES[$i]=$((${ONE[$i]:-0} ^ ${RES[$i]:-0})) + done + shift 1 + done + printf "%02x" "${RES[@]}" +} + +function already_mounted() +{ + # Ausgabe: gemountet = true = 0, nicht gemountet = false = 1 + local AUSGANG + mount | grep -q " ${1} " && AUSGANG=0 || AUSGANG=1 + return $AUSGANG +} + +function mounter() +{ + # Ausgabe: konnte mounten: 0, konnte nicht mounten: 1, schon gemountet 2 + already_mounted "$3" + ERR=$? + if [ "$ERR" -eq 0 ]; then + logger "openslx sharemapper: $3 already mounted." + AUSGANG=2 + else + mount $1 $2 $3 2>/dev/null 1>&2 + ERR=$? + if [ "$ERR" -gt 0 ]; then + logger "openslx sharemapper: could not mount ${2} to ${3}." + AUSGANG=1 + else + logger "openslx sharemapper: ${2} mounted to ${3}." + AUSGANG=0 + fi + fi + return $AUSGANG +} + +### Funktionen Ende ############################### + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/10_preliminaries.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/10_preliminaries.inc new file mode 100644 index 00000000..bcbd6ec1 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/10_preliminaries.inc @@ -0,0 +1,20 @@ +preliminaries_native() +{ + # USERHOMEDIR=~/PERSISTENT, not ~! ################ + [ -h "$USERHOMEDIR" ] && unlink "$USERHOMEDIR" + [ ! -d "$USERHOMEDIR" ] && mkdir -p "$USERHOMEDIR" +} + +preliminaries_vmware() +{ + # USERHOMEDIR=~/PERSISTENT, not ~! ################ + if [ -d "$USERHOMEDIR" ]; then + logger "openslx sharemapper: vmware mode: USERHOMEDIR ${USERHOMEDIR} is a directory, moving to ${USERHOMEDIR}_mov." + mv "$USERHOMEDIR" "${USERHOMEDIR}"_mov + fi + + [ -h "$USERHOMEDIR" ] && unlink "$USERHOMEDIR" + logger "openslx sharemapper: vmware mode: linking $USERHOMEDIR to /mnt/hgfs/home." + ln -s /mnt/hgfs/home "$USERHOMEDIR" || \ + logger "openslx sharemapper: vmware mode: Could not link to vmware hgfs mount dir." +} diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/15_set_trapping.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/15_set_trapping.inc new file mode 100644 index 00000000..c49b99ff --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/15_set_trapping.inc @@ -0,0 +1,14 @@ +function ausgang() +{ rm -f "$KEYTEMP" + rm -f "$RAWKEYTEMP" + # umount "$DISKMOUNTDIR" # as mounted by systemd now. +} + +function set_trapping() +{ + ### Trap ########################################## + trap ausgang EXIT SIGHUP SIGINT SIGTERM + ################################################### +} + +set_trapping diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/20_get_creds.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/20_get_creds.inc new file mode 100644 index 00000000..c6f6ffcb --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/20_get_creds.inc @@ -0,0 +1,27 @@ +function get_creds() +{ + # udp-Socket erzeugen Kanal erzeugen:: + exec 13<>/dev/udp/"$NATADDR"/"$PORT" + + # temp. Datei - wer hat Angst vor Nullbytes? Ich! Ich! Ich! + head -n 1 "$CONFIGFILE" |cut -f3 -d$'\t' | while read -n 2 CODE; do [ -n "$CODE" ] && printf "\x$CODE"; done >"$KEYTEMP" + # Auf Socket fuer Grundsystem schreiben: + cat "$KEYTEMP" >&13 + + # Serverantwort pwdaemon in temp. Datei schreiben: + timeout 2s dd bs=$BYTES count=1 of="$RAWKEYTEMP" <&13 2>/dev/null + + # Kanal zu Socket schließen: + exec 13<&- + exec 13>&- + + # Wieviele Zeichen (Bytes 1 und 2 der Paketnutzlast)? + ANZAHL=$((16#$(dd if=$RAWKEYTEMP bs=1 count=2 2>/dev/null|hexdump -e '1/1 "%02x"'))) + + # Und raus-xor-en: + PW=$( xor $(dd if="$RAWKEYTEMP" bs=1 skip=2 2>/dev/null|hexdump -e '1/1 "%02x"') \ + $(head -n 1 "$CONFIGFILE" | cut -f 4 -d$'\t') | sed 's/../\\x&/g') + + PW=$(echo -e "$PW") # \x...-Ausdrücke zu ASCII + PW="${PW:0:${ANZAHL}}" # ...und Rest nach ANZAHL abhacken. +} diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/30_get_shares.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/30_get_shares.inc new file mode 100644 index 00000000..70b17236 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/30_get_shares.inc @@ -0,0 +1,22 @@ +function get_shares() +{ + i=0 + while read -r LINIE; do + ROHSHARES[i]="$LINIE" + ((i++)) + done < "$CONFIGFILE" + +# echo "${#ROHSHARES[@]} eingelesen:" +# for (( i = 0; i < ${#ROHSHARES[@]}; i++ )); do +# echo -n "$i " +# echo "${ROHSHARES[i]}" +# done + + let SHAREZAHL=${#ROHSHARES[@]}-1 + if [ "$SHAREZAHL" -lt 1 ]; then + logger "openslx sharemapper: No shares to map/mount found in config file $CONFIGFILE." + exit 0 + else + logger "openslx sharemapper: $SHAREZAHL share(s) found." + fi +} diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/30_mount_shares.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/30_mount_shares.inc new file mode 100644 index 00000000..b1320d01 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/30_mount_shares.inc @@ -0,0 +1,66 @@ +function mount_shares() +{ + for (( CONFIGROW = 1; CONFIGROW < ${#ROHSHARES[@]}; CONFIGROW++ )); do + SHAREPATH=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 1 -d$'\t') # cifs- oder nfs-Share + SHARELETTER=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 2 -d$'\t' | \ + sed 's/://g') # Laufwerksbuchstabe ohne : + SHARENAME=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 3 -d$'\t' | sed 's/ /_/g') # Leerzeichen raus. + SHAREUSER=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 4 -d$'\t') # Username, bei Userhome nicht vorhanden + SHAREPASS=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 5 -d$'\t') # User-PW, bei Userhome nicht vorhanden + + # Sharetyp bestimmen: + if [ "${SHAREPATH:0:2}" == '\\' ]; then + USER=$(echo "$SHAREUSER"|cut -d '\' -f 2) + MOUNTOPTS="$MOUNTOPTSCIFS" + else + MOUNTOPTS="$MOUNTOPTSNFS" + fi + + # User-Homeverzeichnis? + if [ "${SHARENAME:0:5}" == "Home-" ]; then + logger "openslx sharemapper: home share \"$SHARENAME\" found (for PERSISTENT)." + export USER="${GLOBALUSER}" + export PASSWD="${PW}" + mounter "${MOUNTOPTS}" ${SHAREPATH} ${USERHOMEDIR} 2>/dev/null 1>&2 + unset USER + unset PASSWD + else + if [ -z "${SHARELETTER}" ]; then + logger "openslx sharemapper: $SHARELETTER not found. Do not know where to mount." + continue + else + USERSHAREDIR="${USERHOME}"/SHARE_"${CONFIGROW}" # ROHSHARES: Zeilennummer; Shares >=1 + if [ ! -d "$USERSHAREDIR" ]; then + mkdir -p "$USERSHAREDIR" 2>/dev/null + chown "$LOCALUSER":$(id --group "$LOCALUSER") "$USERSHAREDIR" + chmod 700 "$USERSHAREDIR" + logger "openslx sharemapper: share mount dir $USERSHAREDIR created." + fi + fi + # Wenn kein Homeverzeichnis, dann share zuerst mit den Credentials aus der share-Konfig + # versuchen zu mounten; wenn nicht, dann mit den Hauptcredentials nachversuchen. + logger "openslx sharemapper: non-home share \"$SHARENAME\" (${CONFIGROW}) found." + export USER="${SHAREUSER}" + export PASSWD="${SHAREPASS}" + mounter "${MOUNTOPTS}" ${SHAREPATH} ${USERSHAREDIR} 2>/dev/null 1>&2 + ERR=$? + if [ "$ERR" -eq 1 ]; then + export USER="${GLOBALUSER}" + export PASSWD="${PW}" + logger "openslx sharemapper: Could not mount ${USERSHAREDIR}, now trying using user credentials." + mounter "${MOUNTOPTS}" ${SHAREPATH} ${USERSHAREDIR} 2>/dev/null 1>&2 \ + ERR=$? # ERR merken wg. Links aus USERSHAREDIR + if [ "$ERR" -eq 1 ]; then + logger "openslx sharemapper: Could not mount ${USERSHAREDIR} even using user credentials; giving up." + fi + unset USER + unset PASSWD + fi + if [ "$ERR" -eq 0 ]; then + logger "openslx sharemapper: Linking ${SHARELETTER} and $SHARENAME, if possible." + [ -n "${SHARELETTER}" ] && ln -s "$USERSHAREDIR" "${USERHOME}"/"$SHARELETTER" + [ -n "${SHARELETTER}" ] && ln -s "$USERSHAREDIR" "${USERHOME}"/"$SHARENAME" + fi + fi + done +} diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/40_check_fallback.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/40_check_fallback.inc new file mode 100644 index 00000000..14a13f77 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/40_check_fallback.inc @@ -0,0 +1,8 @@ +check_fallback() { + if [ $(mount | grep -c " $USERHOMEDIR type cifs \| $USERHOMEDIR type nfs") -lt 1 ]; then + logger "openslx sharemapper: fallback mode: home share check failed, doing fallback to vmware mode." + preliminaries_vmware + else + logger "openslx sharemapper: fallback mode: home share check passed, no fallback necessary." + fi +} diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/50_postliminaries.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/50_postliminaries.inc new file mode 100644 index 00000000..f6f1cf7d --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/50_postliminaries.inc @@ -0,0 +1,21 @@ +postliminaries_native() +{ + # USERHOMEDIR=~/PERSISTENT, not ~! ################ + rmdir "$USERHOMEDIR" && logger "openslx unmounter: home directory entry (PERSISTENT) deleted." \ + || logger "openslx unmounter: could not delete home directory (PERSISTENT) entry - not empty / unmounted!" +} + +postliminaries_vmware() +{ + unlink "$USERHOMEDIR" + ERR=$? + if [ "$ERR" -ne 0 ]; then + logger "openslx unmounter: vmware mode: could not unlink ${USERHOMEDIR}!" + logger "openslx unmounter: vmware mode: this is a severe problem; I do not know what to do - exiting!" + exit 1 + else + logger "openslx unmounter: vmware mode: ${USERHOMEDIR} unlinked." + # checking whether there was a directory moved out earlier: + [ -d "${USERHOMEDIR}"_mov ] && mv "${USERHOMEDIR}"_mov "${USERHOMEDIR}" + fi +} diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/50_umounter.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/50_umounter.inc new file mode 100644 index 00000000..e161b961 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/includes/50_umounter.inc @@ -0,0 +1,12 @@ +umount_home() { + umount /home/"${LOCALUSER}"/PERSISTENT && logger "openslx unmounter: umounted home (PERSISTENT)." \ + || logger "openslx unmounter: could not home (PERSISTENT)!" +} + +umount_shares() { + index=0 + for SHARE in $( mount | grep SHARE | tr -s ' ' | cut -f 3 -d " " ); do + umount "${SHARE}" && logger "openslx unmounter: umounted ${SHARE}." \ + || logger "openslx unmounter: could not umount ${SHARE}!" + done +} diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/mnt_shares b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/mnt_shares new file mode 100755 index 00000000..0c94f0aa --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/mnt_shares @@ -0,0 +1,62 @@ +#!/bin/bash + +# set -x + +logger "openslx sharemapper: Started." + +OWNDIR=$(dirname $0) +for i in "$(dirname $0)"/includes/*.inc; do + source "$i" +done + +# Wait for network connection to base system +#!/bin/bash + +x=1 +while ! ping -w 1 -c 1 "${NATADDR}" 2>/dev/null 1>&2; do + [ "$x" -gt 20 ] && { logger "openslx sharemapper: could not reach base system. Giving up."; exit 1; } + let x=x+1 + sleep 2 +done + +logger "openslx sharemapper: base system reaching; commencing." + +# REMAPMODE (remapMode): 0: None, 1 Native, 2 Native Fallback, 3 vmware +# CREATEMISSING (createMissingRemap): 0: Nichts tun, 1 xdg-Verzeichnisse + +case "$REMAPMODE" in + 0) logger "openslx sharemapper: remapMode 0 (do nothing) detected." + exit 0 + ;; + 1) logger "openslx sharemapper: remapMode 1 (native mode) detected." + preliminaries_native + get_creds # fills global var PW with (currently) decrypted password + get_shares # fills array ROHSHARES; row 0 global infos from (shares-)CONFIGFILE, + # following rows: column 1 share path, col 2 drive letter, col 3 share name, + # column 4 username, col 5 password. + mount_shares # mounts shares given in array ROHSHARES. + exit 0 + ;; + 2) logger "openslx sharemapper: remapMode 2 (fallback mode) detected." + preliminaries_native + get_creds # fills global var PW with (currently) decrypted password + get_shares # fills array ROHSHARES; row 0 global infos from (shares-)CONFIGFILE, + # following rows: column 1 share path, col 2 drive letter, col 3 share name, + # column 4 username, col 5 password. + mount_shares # mounts shares given in array ROHSHARES. + check_fallback # checks for a mounted home and fallbacks to vmware share, if none found. + exit 0 + ;; + 3) logger "openslx sharemapper: remapMode 3 (vmware mode) detected." + preliminaries_vmware + mount_shares # mounts shares given in array ROHSHARES - runvirt checks whether there's + # a home share given or not.. + exit 0 + ;; + *) logger "openslx sharemapper: unknown remapMode in $SLXCONFIGFILE; doing nothing end exiting with error." + exit 1. + ;; +esac + +exit 0 + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/resolution b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/resolution new file mode 100755 index 00000000..24a0594f --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/resolution @@ -0,0 +1,102 @@ +#!/bin/bash + +# Dieses Skript liest die Auflösungsdate HOSTRES.TXT aus der Diskette 2 (/dev/fd1). In dieser +# Datei wird die native (maximale) Auflösung des Grundsystems bereitgestellt. fd1 wird vom +# openslx-Grundsystem geliefert. Es loggt nach SYSLOG (syslog oder messages). +# +# Zu erledigen: Jede Menge, zB anständiges Trapping, Fehler abfangen usw... +# set -x + +MOUNTDIR=/mnt/diskmount +RESFILE="${MOUNTDIR}"/openslx.ini +DISPLAY=:0.0 + +check_resolution() { + # Now, let's wait even more seconds to see if another process re-changes res.: + ACTRES=$(xrandr|grep '*'|tr -s " "|cut -f 2 -d " ") + if [ "$ACTRES" != "$RESOLUTION" ]; then + logger "openslx resolution utility: resolution changed; re-changing." + xrandr --output ${AUSGABE} --mode ${RESOLUTION} + else + logger "openslx resolution utility: resolution unchanged." + fi +} + +logger "openslx resolution utility started." + +# Da nun fremdgemountet wird, hier sicherheitshalber zur Kontrolle wg. Gross-/Kleinschreibung: +RESFILE=$(find "${MOUNTDIR}" -iwholename "${RESFILE}") + +if [ -f "$RESFILE" ]; then + RESOLUTION=$(grep 'resolution=' "$RESFILE" | cut -d '=' -f 2) + if [ -z $RESOLUTION ]; then + logger "openslx resolution utility: resolution file $RESFILE seems to be empty!" + exit 1 + fi + logger "openslx resolution utility: resolution file $RESFILE yields ${RESOLUTION}." +else + logger "openslx resolution utility: resolution file $RESFILE not found!" + exit 1 +fi + +# Das ist mitunter ein Problem, da die richtige zu finden - Distroabhängig! +# Hier ein Beispiel für openSuse 13.2, sollte auch für Debian, Ubuntu, Redhat usw. laufen:. +XAUTHDATEI=$(ps aux | grep -o "X.* \-auth *[^ ]*" | awk '{print $NF}') +if [ -n "$XAUTHDATEI" ]; then + logger "openslx resolution utility: XAUTHFILE found." + XAUTHORITY="${XAUTHDATEI}" +else + logger "openslx resolution utility: XAUTHFILE not found. Exiting." + exit 1 +fi + +# Zu verbessern: Der Name des Verbundenen ist nicht immer bekannt. Daher nehmen wir das +# erste 'connected' in der Ausgabe xrandrs: +AUSGABE=$(xrandr -q|grep -m 1 " connected "|awk '{print $1}') +if [ -z "$AUSGABE" ]; then + logger "openslx resolution utility: Could not detect output device. Exiting." + exit 1 +fi + +# Pruefen, ob xrand eine passende modeline ausgibt: +if [ "$(xrandr | grep -c ${RESOLUTION})" -eq 0 ]; then + logger "openslx resolution utility: xrandr yields no fitting modeline; adding one." + MODELINE=$(cvt ${RESOLUTION//x/ } | grep -v "^#" | sed "s/Modeline //g" | sed 's/"//g') + xrandr --newmode $(echo ${MODELINE}) + xrandr --addmode ${AUSGABE} $(echo ${MODELINE} | cut -d " " -f 1) + # Dann einzusteuernde Auflösung natürlich auf die neue ändern: + RESOLUTION=$(echo ${MODELINE} | cut -d " " -f 1) + logger "openslx resolution utility: (xrandr) modeline ${MODELINE} added (${RESOLUTION})." +fi + +# Auflösung per xrandr setzen: +xrandr --output ${AUSGABE} --mode ${RESOLUTION} +ERR=$? +if [ $ERR -ne 0 ]; then + logger "openslx resolution utility: xrandr error code ${ERR}." +else + logger "openslx resolution utility: xrandr ok. Mode $RESOLUTION set." +fi + +# Das hier ist ein wenig problematisch, da nach X-Start die gewünschte Desktopumgebung +# diese gern zuvor gespeicherte Auflösungen wieder einspielt. Daher warten wir einfach, +# und prüfen in gewissen Zeitabständen, ob sich die Auflösung geändert hat, und spielen +# im Änderungsfalle die Grundsystemauflösung wieder ein. Schön ist das nicht. + +# Now, let's wait some seconds to see if another process re-changes res.: +sleep 5 +check_resolution + +# Now, let's wait some more seconds to see if another process re-changes res.: +sleep 15 +check_resolution + +# Now, let's wait even more seconds to see if another process re-changes res.: +sleep 20 +check_resolution + +# Now, let's wait even more seconds to see if another process re-changes res.: +sleep 40 +check_resolution + +exit 0 diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/resolution_standalone b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/resolution_standalone new file mode 100755 index 00000000..0dbbcf98 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/resolution_standalone @@ -0,0 +1,138 @@ +#!/bin/bash + +# Dieses Skript liest die Auflösungsdate HOSTRES.TXT aus der Diskette 2 (/dev/fd1). In dieser +# Datei wird die native (maximale) Auflösung des Grundsystems bereitgestellt. fd1 wird vom +# openslx-Grundsystem geliefert. Es loggt nach SYSLOG (syslog oder messages). +# +# Zu erledigen: Jede Menge, zB anständiges Trapping, Fehler abfangen usw... +# set -x + +MOUNTDIR=/tmp/diskmount +RESFILE="${MOUNTDIR}"/openslx.ini +DISPLAY=:0.0 + +function ausgang() { + umount "${MOUNTDIR}" + rmdir "${MOUNTDIR}" +} + +check_resolution() { + # Now, let's wait even more seconds to see if another process re-changes res.: + ACTRES=$(xrandr|grep '*'|tr -s " "|cut -f 2 -d " ") + if [ "$ACTRES" != "$RESOLUTION" ]; then + logger "openslx resolution utility: resolution changed; re-changing." + xrandr --output ${AUSGABE} --mode ${RESOLUTION} + else + logger "openslx resolution utility: resolution unchanged." + fi +} + +trap ausgang EXIT SIGHUP SIGINT SIGTERM + +logger "openslx resolution utility started." + +# Mountpunkt erzeugen: +if [ ! -d "$MOUNTDIR" ]; then + mkdir "$MOUNTDIR" + logger "openslx resolution utility: mkdir'ed diskmount dir $MOUNTDIR." +fi + +# Virtuelles Floppylaufwerk mounten +mount /dev/fd1 "$MOUNTDIR" 2>/dev/null +ERR=$? +if [ $ERR -ne 0 ]; then + logger "openslx resolution utility: error code $ERR trying to mount /dev/fd1 to ${MOUNTDIR}. Remounting..." + mount -o remount /dev/fd1 "$MOUNTDIR" 2>/dev/null + ERR=$? + if [ $ERR -ne 0 ]; then + logger "openslx resolution utility: error code $ERR trying to remount /dev/fd1 to ${MOUNTDIR}. Giving up." + exit 1 + else + logger "openslx resolution utility: remount of /dev/fd1 mounted to diskmount dir ${MOUNTDIR} succeeded." + fi +else + logger "openslx resolution utility: /dev/fd1 mounted to diskmount dir ${MOUNTDIR}." +fi + +# Das Mounten mit shortname=WIN95 erwies sich als nicht zuverlässig. Daher hier Kontrolle: +RESFILE=$(find "${MOUNTDIR}" -iwholename "${RESFILE}") + +if [ -f "$RESFILE" ]; then + RESOLUTION=$(grep 'resolution=' "$RESFILE" | cut -d '=' -f 2) + if [ -z $RESOLUTION ]; then + logger "openslx resolution utility: resolution file $RESFILE seems to be empty!" + exit 1 + fi + logger "openslx resolution utility: resolution file $RESFILE yields ${RESOLUTION}." +else + logger "openslx resolution utility: resolution file $RESFILE not found!" + exit 1 +fi + +umount /dev/fd1 +ERR=$? +if [ "$ERR" -ne 0 ]; then + logger "openslx resolution utility: error code $ERR trying to to unmount /dev/fd1. Please unmount by hand." +fi + +# Das ist mitunter ein Problem, da die richtige zu finden - Distroabhängig! +# Hier ein Beispiel für openSuse 13.2, sollte auch für Debian, Ubuntu, Redhat usw. laufen:. +XAUTHDATEI=$(ps aux | grep -o "X.* \-auth *[^ ]*" | awk '{print $NF}') +if [ -n "$XAUTHDATEI" ]; then + logger "openslx resolution utility: XAUTHFILE found." + XAUTHORITY="${XAUTHDATEI}" +else + logger "openslx resolution utility: XAUTHFILE not found. Exiting." + exit 1 +fi + +# Zu verbessern: Der Name des Verbundenen ist nicht immer bekannt. Daher nehmen wir das +# erste 'connected' in der Ausgabe xrandrs: +AUSGABE=$(xrandr -q|grep -m 1 " connected "|awk '{print $1}') +if [ -z "$AUSGABE" ]; then + logger "openslx resolution utility: Could not detect output device." + exit 1 +fi + +# Pruefen, ob xrand eine passende modeline ausgibt: +if [ "$(xrandr | grep -c ${RESOLUTION})" -eq 0 ]; then + logger "openslx resolution utility: xrandr yields no fitting modeline; adding one." + MODELINE=$(cvt ${RESOLUTION//x/ } | grep -v "^#" | sed "s/Modeline //g" | sed 's/"//g') + xrandr --newmode $(echo ${MODELINE}) + xrandr --addmode ${AUSGABE} $(echo ${MODELINE} | cut -d " " -f 1) + # Dann einzusteuernde Auflösung natürlich auf die neue ändern: + RESOLUTION=$(echo ${MODELINE} | cut -d " " -f 1) + logger "openslx resolution utility: (xrandr) modeline ${MODELINE} added (${RESOLUTION})." +fi + +# Auflösung per xrandr setzen: +xrandr --output ${AUSGABE} --mode ${RESOLUTION} +ERR=$? +if [ $ERR -ne 0 ]; then + logger "openslx resolution utility: xrandr error code ${ERR}." +else + logger "openslx resolution utility: xrandr ok. Mode $RESOLUTION set." +fi + +# Das hier ist ein wenig problematisch, da nach X-Start die gewünschte Desktopumgebung +# diese gern zuvor gespeicherte Auflösungen wieder einspielt. Daher warten wir einfach, +# und prüfen in gewissen Zeitabständen, ob sich die Auflösung geändert hat, und spielen +# im Änderungsfalle die Grundsystemauflösung wieder ein. Schön ist das nicht. + +# Now, let's wait some seconds to see if another process re-changes res.: +sleep 5 +check_resolution + +# Now, let's wait some more seconds to see if another process re-changes res.: +sleep 15 +check_resolution + +# Now, let's wait even more seconds to see if another process re-changes res.: +sleep 20 +check_resolution + +# Now, let's wait even more seconds to see if another process re-changes res.: +sleep 40 +check_resolution + +exit 0 diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/umnt_shares b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/umnt_shares new file mode 100755 index 00000000..b028cf76 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/umnt_shares @@ -0,0 +1,40 @@ +#!/bin/bash + +# set -x + +logger "openslx sharemapper: umounter started." + +OWNDIR=$(dirname $0) +for i in "$(dirname $0)"/includes/*.inc; do + source "$i" +done + +# REMAPMODE (remapMode): 0: None, 1 Native, 2 Native Fallback, 3 vmware +# CREATEMISSING (createMissingRemap): 0: Nichts tun, 1 xdg-Verzeichnisse + +case "$REMAPMODE" in + 0) logger "openslx sharemapper: umounter: remapMode 0 (do nothing) detected." + exit 0 + ;; + 1) logger "openslx sharemapper: umounter: remapMode 1 (native mode) detected." + umount_shares + umount_home + postliminaries_native + ;; + 2) logger "openslx sharemapper: umounter: remapMode 2 (fallback mode) detected." + umount_shares + umount_home + postliminaries_native + exit 0 + ;; + 3) logger "openslx sharemapper: umounter: remapMode 3 (vmware mode) detected." + postliminaries_vmware + exit 0 + ;; + *) logger "openslx sharemapper: umounter: unknown remapMode in $SLXCONFIGFILE; doing nothing end exiting with error." + exit 1. + ;; +esac + +exit 0 + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/vm_installer b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/vm_installer new file mode 100755 index 00000000..978cee20 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/vm_installer @@ -0,0 +1,87 @@ +#!/bin/bash + +PS=$(which ps) +GREP=$(which grep) +LOGGER=$(which logger) +MKDIR=$(which mkdir) +MOUNT=$(which mount) +MOUNTDIR=/mnt/diskmount/ +SERVICEFILE=openslx-scriptinstall.service + +# systemd erkennen +case $(${PS} --pid 1 -o comm h) in + systemd) echo "openslx praeinstaller: systemd detected." + if [ -d /etc/systemd/system ]; then + SERVICEDIR=/etc/systemd/system/ + else + SERVICEDIR=/usr/lib/systemd/system/ + fi + echo "openslx praeinstaller: installing systemd service file to ${SERVICEDIR}/${SERVICEFILE}." + + cat <<-HEREDOC > "$SERVICEDIR"/"$SERVICEFILE" + [Unit] + Description=openSLX script installer + Before=display-manager.service graphical.target + + [Service] + Type=oneshot + ExecStartPre=${MKDIR} -p /mnt/diskmount + ExecStartPre=-${MOUNT} /dev/fd1 /mnt/diskmount + ExecStart=${LOGGER} "openslx service file: started." + ExecStart=${MOUNTDIR}/linux/vm_runtime + ExecStart=${LOGGER} "openslx service file: done." + RemainAfterExit=no + HEREDOC + + [ ! -d /etc/systemd/system/graphical.target.wants ] && mkdir /etc/systemd/system/graphical.target.wants 2>/dev/null + [ ! -d /etc/systemd/system/basic.target.wants ] && mkdir /etc/systemd/system/basic.target.wants 2>/dev/null + + ln -s "${SERVICEDIR}"/"${SERVICEFILE}" /etc/systemd/system/graphical.target.wants/"${SERVICEFILE}" + ln -s "${SERVICEDIR}"/"${SERVICEFILE}" /etc/systemd/system/basic.target.wants/"${SERVICEFILE}" + + echo "openslx praeinstaller: doing systemd reload." + systemctl daemon-reload + ;; + init) echo "openslx praeinstaller: init(V) detected." + SERVICEDIR=/etc/init.d/ + [ ! -d "${SERVICEDIR}" ] && { echo "openslx praeinstaller: No init directory $SERVICEDIR found, exiting."; exit 1; } + SERVICEFILE=openslx-scriptinstall + echo "openslx praeinstaller: installing init service file to ${SERVICEDIR}/${SERVICEFILE}." + cat <<-THEREDOC > "${SERVICEDIR}"/"${SERVICEFILE}" + #!/bin/sh -e + ### BEGIN INIT INFO + # Provides: openSLX_scriptinstaller + # Required-Start: 2 3 4 5 + # Required-Stop: 0 1 6 + # Default-Start: 2 3 4 5 + # Default-Stop: 0 1 6 + # X-Interactive: false + # Short-Description: openSLX script package starter. + ### END INIT INFO + # + # Starts via Xsetup patching the openSLX script package + # to correct screen resolution and mount network shares + # when Xsetup is started. + + case "\$1" in + start) ${LOGGER} "openslx init file: started." + ${MKDIR} -p /mnt/diskmount + ${MOUNT} | ${GREP} -q /mnt/diskmount || ${MOUNT} /dev/fd1 /mnt/diskmount + ${MOUNTDIR}/linux/vm_runtime + ${LOGGER} "openslx init file: done." + ;; + stop|restart|force-reload) exit 0 ;; + *) echo "Usage: $0 {start}" >&2; exit 1 ;; + esac + THEREDOC + chmod +x "${SERVICEDIR}"/"${SERVICEFILE}" + echo "openslx praeinstaller: enabling ${SERVICEFILE}." + update-rc.d "${SERVICEFILE}" defaults + ;; + *) echo "openslx praeinstaller: Could not determine mother-of-all-processes (not systemd, not init)." + echo "openslx praeinstaller: Giving up, exiting." + exit 1 +esac + +exit 0 + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/vm_runtime b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/vm_runtime new file mode 100755 index 00000000..0a81c38d --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/linux/vm_runtime @@ -0,0 +1,97 @@ +#!/bin/bash + +# set -x + +# logger "openslx vm_runtime: Started." + +DISTRIBUTION=$(lsb_release -is | tr '[A-Z]' '[a-z]' | sed -r 's/[^a-z0-9]//g;s/project$//g;s/scientificsl$/scientific/g') +VERSION=$(lsb_release -rs) +SCRIPTDIR=/mnt/diskmount/linux/ +RESOLUTIONSCRIPT="${SCRIPTDIR}"/resolution +SHARESCRIPT="${SCRIPTDIR}"/mnt_shares +UMOUNTSCRIPT="${SCRIPTDIR}"/umnt_shares +XSETUP=$(find /etc/X* -name "Xsetup" 2>/dev/null) +XRESET=$(find /etc/X* -name "Xreset" 2>/dev/null) + +[ ! -f "${RESOLUTIONSCRIPT}" -o ! -f "${SHARESCRIPT}" ] && \ + { logger "openslx vm_runtime: could not find needed scripts on disk. Exiting." ; exit 1 ; } + +write_xsetup() { + logger "openslx vm_runtime: writing ${XSETUP}..." + cat<<-BISHIER > "${XSETUP}" + #!/bin/sh + ${SHARESCRIPT} & + ${RESOLUTIONSCRIPT} & + BISHIER +} + +patch_xsetup_shebang() { + # Patching after first line, to be exact. + logger "openslx vm_runtime: patching ${XSETUP} after shebang line, if necessary." + grep -q "${RESOLUTIONSCRIPT}" "${XSETUP}" || sed "1 a ${RESOLUTIONSCRIPT} \&" -i "${XSETUP}" + grep -q "${SHARESCRIPT}" "${XSETUP}" || sed "1 a ${SHARESCRIPT} \&" -i "${XSETUP}" +} + +write_xreset() { + logger "openslx vm_runtime: writing ${XRESET}..." + cat<<-BISHIER > "${XRESET}" + #!/bin/sh + ${UMOUNTSCRIPT} & + BISHIER +} + +patch_xreset_shebang() { + # Patching after first line, to be exact. + logger "openslx vm_runtime: patching ${XRESET} after shebang line, if necessary." + grep -q "${UMOUNTSCRIPT}" "${XRESET}" || sed "1 a ${UMOUNTSCRIPT} \&" -i "${XRESET}" +} + +case "${DISTRIBUTION}" in + opensuse) logger "openslx vm_runtime: openSuse detected." + if [ ! -e "${XSETUP}" ]; then + XSETUP=/etc/X11/xdm/Xsetup + write_xsetup + else + logger "openslx vm_runtime: patching ${XSETUP}." + if ! [ grep -c /etc/sysconfig/displaymanager "$XSETUP" 2>/dev/null 1>&2 ]; then + logger "openslx vm_runtime: Xsetup: openSuse marker found, patching." + sed "s#/etc/sysconfig/displaymanager#/etc/sysconfig/displaymanager\n"${SHARESCRIPT}" \&\n${RESOLUTIONSCRIPT} \&#g" \ + -i "${XSETUP}" + else + logger "openslx vm_runtime: Xsetup: openSuse marker not found, patching after shebang line." + xsetup_patch_shebang + fi + logger "openslx vm_runtime: patching ${RESET}." + patch_xreset_shebang + fi + ;; + ubuntu) logger "openslx vm_runtime: Ubuntu detected, version ${VERSION}." + # Ubuntu has at least in version 14.04 LTS a bug leading to missing Xsetup/Xreset entries: + grep -q "session-setup-script=/etc/X11/Xsetup" /etc/lightdm/lightdm.conf.d/50-myconfig.conf \ + || { sed "$ a session-setup-script=/etc/X11/Xsetup" -i /etc/lightdm/lightdm.conf.d/50-myconfig.conf + logger "openslx vm_runtime: session-setup-script patched into /etc/lightdm/lightdm.conf.d/50-myconfig.conf."; } + grep -q "session-reset-script=/etc/X11/Xreset" /etc/lightdm/lightdm.conf.d/50-myconfig.conf \ + || { sed "$ a session-reset-script=/etc/X11/Xreset" -i /etc/lightdm/lightdm.conf.d/50-myconfig.conf + logger "openslx vm_runtime: session-reset-script patched into /etc/lightdm/lightdm.conf.d/50-myconfig.conf."; } + if [ ! -e "${XSETUP}" ]; then + XSETUP=/etc/X11/Xsetup + write_xsetup + else + patch_xsetup_shebang + fi + if [ ! -e "${XRESET}" ]; then + XRESETP=/etc/X11/Xreset + write_xreset + else + patch_xreset_shebang + fi + ;; + debian) logger "openslx vm_runtime: Debian detected." + ;; + *) logger "openslx vm_runtime: Unknown distribution, exiting." + exit 1 + ;; +esac + +exit 0 + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe b/core/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe Binary files differindex 114a0dc0..c0904c92 100755 --- a/core/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/download_vm_metadata.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/download_vm_metadata.inc new file mode 100644 index 00000000..974a5626 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/download_vm_metadata.inc @@ -0,0 +1,32 @@ +######################################################## +# Include: Detect, whether runvirt runs in legacy mode # +######################################################## + +# Legacy mode: As runvirt has been before. +# New mode: uuid in xml _and_ vmx given via http. + +writelog "Detecting current/legacy mode ..." + +declare -rg TMPCONFIG="$TMPDIR/vmconfig.tmp" + +# Assume legacy mode by default, only trigger "current" mode if everything else below worked +LEGACY=yes +if [ -z "$IMGUUID" ]; then # Keine uuid: Abbruch, Legacy + writelog "Could not extract a uuid param from ${xmlfile}. Triggering legacy mode." +else + # Now getting template file: + if ! wget -T 6 -O "$TMPCONFIG" "${SLX_VMCHOOSER_BASE_URL}/lecture/${IMGUUID}" 2>/dev/null >&2; then + writelog "wget ${SLX_VMCHOOSER_BASE_URL}/lecture/${IMGUUID}. Triggering legacy mode." + else + writelog "wget ${SLX_VMCHOOSER_BASE_URL}/lecture/${IMGUUID} successful." + if [ ! -s "$TMPCONFIG" ]; then + writelog "Server sent zero byte virtual machine description file. Triggering legacy mode." + else + writelog "Triggering current (non-legacy) mode." + LEGACY= # everything worked - clear legacy mode variable (so we use the "current" mode) + fi + fi +fi + +readonly LEGACY + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/get_xml_file_variables.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/get_xml_file_variables.inc new file mode 100644 index 00000000..fdacc69c --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/get_xml_file_variables.inc @@ -0,0 +1,63 @@ +############################################ +# Include: Get needed values from XML file # +############################################ + +writelog "Parsing XML..." + +declare -rg VMSTORE_PATH=/mnt/vmstore + +get_xml () { + xmlextract "//settings/eintrag/${1}/@param" "${xmlfile}" +} + +IMGUUID=$(get_xml "uuid") + +# # Name of the virt image +SRC_IMG_ABSOLUTE=$(get_xml "image_path") +SRC_IMG_RELATIVE=$(get_xml "image_name") + +if [ -z "${SRC_IMG_ABSOLUTE}${SRC_IMG_RELATIVE}" ]; then + writelog "Neither relative nor absolute path for image found in xml" + cleanexit 1 +fi + +if [ -n "$SRC_IMG_ABSOLUTE" ] && [ "${SRC_IMG_ABSOLUTE:0:1}" != "/" ]; then + writelog "Error parsing XML for absolute image path: given value doesn't start with '/': '$SRC_IMG_ABSOLUTE'" + cleanexit 1 +fi + +if [ -z "$SRC_IMG_ABSOLUTE" ]; then + SRC_IMG_ABSOLUTE="${VMSTORE_PATH}/${SRC_IMG_RELATIVE}" +fi + +IMG_BASENAME=$(basename "$SRC_IMG_ABSOLUTE") +writelog "Virtual image file name: $IMG_BASENAME" + +VM_DISPLAYNAME=$(get_xml "short_description") +[ -z "$VM_DISPLAYNAME" ] && VM_DISPLAYNAME="${IMG_BASENAME}" + +# Define VM_NAME_CLEAN since VM_DISPLAYNAME can be long and contain weird characters +VM_NAME_CLEAN=$(echo "${VM_DISPLAYNAME:0:32}" | sed -r 's/[^0-9a-zA-Z_-\.]+/_/g') + +# image is for the following virtual machine +PLUGIN_ID=$(grep -o 'virtualmachine param=.*"' "${xmlfile}" \ + | sed -e "s/&.*;/; /g" | awk -F '"' '{print $2}') + +# Extracting OS type (VM_OS_TYPE) from xml file. We don't care here whether VM_OS_TYPE is empty, as then +# it will yield the default entries later on. +VM_OS_TYPE=$(get_xml "os") + +readonly IMGUUID +readonly SRC_IMG_ABSOLUTE SRC_IMG_RELATIVE +readonly IMG_BASENAME +readonly VM_DISPLAYNAME VM_NAME_CLEAN +readonly PLUGIN_ID +readonly VM_OS_TYPE + +writelog "VM UUID: $IMGUUID" +writelog "Virtualization plugin: $PLUGIN_ID" +writelog "VM name: $VM_DISPLAYNAME" +writelog "VM short name: $VM_NAME_CLEAN" +writelog "VM OS: $VM_OS_TYPE" +writelog "Done parsing XML." + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/set_runvirt_hardware_variables.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/set_runvirt_hardware_variables.inc new file mode 100644 index 00000000..508c9efe --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/set_runvirt_hardware_variables.inc @@ -0,0 +1,113 @@ +########################################### +# Include: Set hardware related variables # +########################################### + +get_vm_id() { + local script=${BASH_SOURCE[-1]} + [ -z "$script" ] && script="$0" + if [ -n "$script" ]; then + script=$(readlink -f "$script") + if [ -n "$script" ] && [ -s "$script" ]; then + #bingo + VM_ID=$(ps ax | grep -F "$script" | grep -v 'grep' | grep -o -- "${script}.*\$" | sort -u | wc -l) + if [ "$VM_ID" -gt 0 ]; then + [ "${#VM_ID}" -eq 1 ] && VM_ID="0${VM_ID}" + [ "${#VM_ID}" -gt 2 ] && VM_ID="${VM_ID:0:2}" + [ "${#VM_ID}" -eq 2 ] && return + fi + fi + fi + # fallback: take last two digits of current pid... + VM_ID=$(expr substr $$ $(expr ${#$} - 1) 2) + [ "${#VM_ID}" -eq 1 ] && VM_ID="0${VM_ID}" +} + +get_vm_id + +# Make sure cpu_cores is not empty +cpu_cores=${cpu_cores:-"1"} + +# Amount of memory for the VM. Be generous if diff is written to HDD +if mount | grep -q '^/dev/sd.*on.*/tmp'; then + reserve=20 + min=768 + max=1800 +else + reserve=65 + min=768 + max=8192 +fi + +# Calculate absulute amount of RAM that should stay available to the host +reserve="$(( ( totalmem * reserve ) / 100 ))" +# Respect some upper and lower bounds for the host amount +[ "$reserve" -lt "$min" ] && reserve="$min" +[ "$reserve" -gt "$max" ] && reserve="$max" + +# Get a result which can be divided by 4 +mem="$(( ( ( totalmem - reserve ) / 4 ) * 4 ))" +if [ -n "$mainvirtmem" ]; then + forcemem="$(( mainvirtmem / 4 * 4 ))" + mem="$forcemem" +fi +hostmem="$(( totalmem - mem ))" + +# Fill in VMID +macaddrsuffix=$(echo "$macaddrsuffix" | sed "s/%VMID%/${VM_ID}/") + +if ! echo "$macaddrprefix" | grep -q -E '^[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}$'; then + slxlog "virt-mac" "Could not properly generate mac address prefix (got $macaddrprefix)" +fi +if ! echo "$macaddrsuffix" | grep -q -E '^[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}$'; then + slxlog "virt-mac" "Could not properly generate mac address suffix (got $macaddrsuffix)" +fi +macaddr="$macaddrprefix:$macaddrsuffix" + +# Virtual fd/cd/dvd and drive devices, floppy b: for configuration +# if $floppy_0 from virtualization.conf set then fdtest="TRUE" +fdtest=${floppy_0:+"TRUE"} +# if $fdtest not set floppy0="FALSE", else "TRUE" +floppy0=${fdtest:-"FALSE"} +# if $cdrom_0 from virtualization.conf set then cdtest="TRUE" +cdtest=${cdrom_0:+"TRUE"} +# if $cdtest not set cdrom0="FALSE", else "TRUE" +cdrom0=${cdtest:-"FALSE"} +# if $cdrom_1 from virtualization.conf set then cdtest="TRUE" +cdtest=${cdrom_1:+"TRUE"} +# if $cdtest not set cdrom1="FALSE", else "TRUE" +cdrom1=${cdtest:-"FALSE"} + +# Dynamically detect serial ports here instead of at boot time +# (virtualization.conf), since USB serial ports get quite common +# and might not be plugged in at boot time yet +serial_0= +#for port in $(awk '{ if ($1 ~ /^[0-9]+:/ && $2 != "uart:unknown") print "/dev/ttyS" sub(/:\$/, "", $1) }' /proc/tty/driver/serial); do +for port in $serial_ports /dev/ttyUSB*; do + [ -c "$port" ] || continue + serial_0="$port" + break +done + +parallel_0= +for port in /dev/parport*; do + [ -c "$port" ] || continue + parallel_0="$port" + break +done + +# RDP/VNC port (59001 - 59099) +remotedesktopport="590${VM_ID}" + +# Add rw share for home dir +homesharepath="${HOME}/PERSISTENT" +homesharename="home" + +# Add common share +commonsharepath="${HOME}/SHARE" +commonsharename="share" + +# Set hostname: using original hostname and adding string +hostname="virt-$(hostname)" + +writelog "\tVM Hostname:\t\t$hostname" + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/set_runvirt_variables.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/set_runvirt_variables.inc new file mode 100644 index 00000000..cd9a573a --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/set_runvirt_variables.inc @@ -0,0 +1,26 @@ +###################################################### +# Include: Declaration of run-virt default variables # +###################################################### + +VMCHOOSER_DIR="/opt/openslx/vmchooser" +VMCHOOSER_CONF_DIR="$VMCHOOSER_DIR/config" +USER="$(whoami)" +LOGFILE="/var/log/openslx/run-virt.${USER}.$$.log" +TMPDIR="/tmp/virt/${USER}/$$" + +readonly VMCHOOSER_DIR VMCHOOSER_CONF_DIR LOGFILE TMPDIR USER + +# include general configuration from vmchooser +[ -f "$VMCHOOSER_CONF_DIR/vmchooser.conf" ] && . "$VMCHOOSER_CONF_DIR/vmchooser.conf" +# load general virtualization information +[ -f "$VMCHOOSER_CONF_DIR/virtualization.conf" ] && . "$VMCHOOSER_CONF_DIR/virtualization.conf" +# Load general openslx config +[ -f "/opt/openslx/config" ] && . "/opt/openslx/config" +# Create temp dir +if ! mkdir -p "$TMPDIR"; then + slxlog "virt-tmpdir" "Could not create temporary directory '$TMPDIR' for session" + error_user "Konnte kein temporäres Arbeitsverzeichnis für die VM-Sitzung anlegen. Ein Computer-Neustart könnte das Problem lösen." + cleanexit 1 + exit 1 +fi + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_firewall.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_firewall.inc new file mode 100644 index 00000000..f0820ed7 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_firewall.inc @@ -0,0 +1,12 @@ + +setup_firewall () { + local LOGF="${TMPDIR}/firewall.log" + local RET + [ "$DISPLAY" = ":0" ] || return 0 # For now, to avoid conflicts, we only do this on display :0 + slxfwtool "$IMGUUID" > "$LOGF" 2>&1 + RET=$? + if [ "$RET" != "0" ]; then + slxlog "runvirt-firewall" "Error setting up firewall rules for lecture $IMGUUID (Exit code $RET)" "$LOGF" + fi + return 0 +} diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_image_access.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_image_access.inc new file mode 100644 index 00000000..4240d9ca --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_image_access.inc @@ -0,0 +1,98 @@ +########################################################### +# Include: Setup dnbd for image access, nfs/cifs fallback # +########################################################### + +# This will currently make sure that the variable +# VM_DISKFILE_RO is set which will contain the +# absolute path to the disk image to use for the vm +# session. +# When using DNBD3 this will differ from SRC_IMG_ABSOLUTE, +# otherwise it will be identical. +# In the future DNBD3 (or something else) might provide +# a CoW layer so we don't need snapshots etc. anymore. +# This include should set VM_DISKFILE_RW in that case to +# indicate to the virt plugin that it doesn't need to +# handle creating a temporary CoW layer itself. + +writelog "Setting up disk access for virtualizer/emulator ..." + +# Try to use dnbd3 to access the image +unset VM_DISKFILE_RO +unset dnbd3_fuse_mount_point + +setup_dnbd3 () { + # Mount path for images mounted with dnbd3-fuse + dnbd3_fuse_mount_point="$TMPDIR/dnbd3fuse.mnt" + mkdir -p "${dnbd3_fuse_mount_point}" + # start dnbd3-fuse in subshell + local dnbd3_tmplog="$TMPDIR/dnbd3fuse.log" + local dnbd3_exitflag="$TMPDIR/dnbd3exit$RANDOM" + local TIMEOUT vm_revision + rm -f -- "$dnbd3_exitflag" + ( + dnbd3-fuse -f -o allow_other,max_readahead=262144 -h "$SLX_DNBD3_SERVERS" -i "${SRC_IMG_RELATIVE}" "${dnbd3_fuse_mount_point}" > "$dnbd3_tmplog" 2>&1 + RET=$? + touch "$dnbd3_exitflag" + if [ "$RET" != "0" ]; then + writelog "dnbd3-fuse stopped working (Exit code $RET)" + slxlog "virt-dnbd3-fuse" "dnbd3-fuse stopped/refused serving '${SRC_IMG_RELATIVE}' from '${SLX_DNBD3_SERVERS}' with error code: $RET" "${dnbd3_tmplog}" + fi + ) & + # give it a bit of time + usleep 250000 + # check if we have the image + for TIMEOUT in 0.5 1 1 OUT; do + if [ -r "${dnbd3_fuse_mount_point}/img" ]; then + vm_revision="$(grep -m 1 "^Revision:" "${dnbd3_fuse_mount_point}/status" | cut -d" " -f2)" + VM_DISKFILE_RO="${dnbd3_fuse_mount_point}/img" + writelog "DNBD3: $SRC_IMG_RELATIVE on $VM_DISKFILE_RO with rid $vm_revision" + break + fi + [ "$TIMEOUT" = "OUT" -o -e "$dnbd3_exitflag" ] && break + sleep "$TIMEOUT" + done + + if [ -z "$VM_DISKFILE_RO" ]; then + slxlog "virt-dnbd3" "No dnbd3 server for ${SRC_IMG_RELATIVE} found, trying NFS/CIFS..." "$dnbd3_tmplog" + writelog "No working dnbd3 server found :-(" + fi +} + +# See if we should setup dnbd3 image access at all +if ! which dnbd3-fuse; then + writelog "Can't use dnbd3 as dnbd3-fuse binary is not in PATH" +elif [ -z "$SRC_IMG_RELATIVE" ]; then + writelog "Can't use dnbd3 as SRC_IMG_RELATIVE is not set" +elif [ -z "$SLX_DNBD3_SERVERS" ] || [ "x$SLX_VM_DNBD3" != "xyes" ]; then + writelog "Can't use dnbd3 as no servers are given in config, or SLX_VM_DNBD3 is not set to yes" +else + setup_dnbd3 +fi + +# VM_DISKFILE_RO will be empty if dnbd3 is not used or failed to connect. +# Let's try to fall back to NFS/CIFS via file system +if [ -z "$VM_DISKFILE_RO" ]; then + # Maybe we're reading a dnbd3 directory with RIDs encoded into the filename - use latest one + rid_suffix=$(ls -1 "${SRC_IMG_ABSOLUTE}.r"* | grep -E -o '\.r[0-9]+$' | grep -o -E '[0-9]+$' | sort -n | tail -n 1) + if [ -n "$rid_suffix" ]; then + # found + VM_DISKFILE_RO="${SRC_IMG_ABSOLUTE}.r${rid_suffix}" + elif [ -e "$SRC_IMG_ABSOLUTE" ]; then + # try name we got from xml in the first place + VM_DISKFILE_RO="$SRC_IMG_ABSOLUTE" + fi +fi + +# Check if virtual machine container file exists +if [ -z "$VM_DISKFILE_RO" ] || ! [ -e "${VM_DISKFILE_RO}" ]; then + slxlog "virt-image-missing" "VM image $VM_DISKFILE_RO not found!" + writelog "Virtual machine image ${VM_DISKFILE_RO} not found!" + error_user "Das Image für die gewählte Virtuelle Maschine konnte nicht gefunden werden. +Versuchen Sie zunächst, den Computer komplett neu zu starten. Sollte das Problem bestehen bleiben, wenden Sie sich bitte an den Support." + cleanexit 1 +fi + +readonly VM_DISKFILE_RO + +writelog "Disk file to use: $VM_DISKFILE_RO" + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_printer_lpd.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_printer_lpd.inc new file mode 100644 index 00000000..2fb9310a --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_printer_lpd.inc @@ -0,0 +1,46 @@ +##################################### +# Include: Setup printer daemon LPD # +##################################### + +QUEUE="STANDARD" # This has to match the queue you configured in your VM +SPOOLDIR= + +### Disabled: 100megs is not enough, some jobs are HUGE, try to use temp which should be on disk +## Try using user's tmpfs home first, as it gets wiped on logout +#if [ -n "${HOME}" ] && [ -w "${HOME}" ]; then +# SPOOLDIR="${HOME}/.spool" +# mkdir -p "${SPOOLDIR}/${QUEUE}" +#fi +# If failed, try to fall back to /tmp + +if [ -z "${SPOOLDIR}" ] || [ ! -w "${SPOOLDIR}/${QUEUE}" ]; then + SPOOLDIR="${TMPDIR}/printergui-${RANDOM}" + rm -rf -- "${SPOOLDIR}" + if ! mkdir -p "${SPOOLDIR}/${QUEUE}"; then + slxlog "virt-spooldir" "Could not create spool directory ($SPOOLDIR) for $USER - printing will not work!" + # TODO: Warn user + fi + chmod 0700 "${SPOOLDIR}/${QUEUE}" +fi + +# Start the lpdaemon listening on the given port +# TODO: externalize with something like runvirt.d (other parts might benefit from that too) +tcpsvd -E 192.168.101.1 5515 \ + lpd "$SPOOLDIR" \ + ash -c "/opt/openslx/scripts/run-virt_print '${USER}' \"${SPOOLDIR}/${QUEUE}/\$DATAFILE\"" & + +# PID to kill the process +PID_LPD="$!" + +{ + sleep 2 + # Check if tcpsvd is running. Do this a little delayed so we do not check + # immediately after trying to spawn it, as this could result in + # success even if it's not really working. + + if ! kill -0 "$PID_LPD"; then + slxlog "virt-lpd" "Could not start tcpsvd/lpd for virtual machine session" + notify_user "Durcksystem" "Das Drucksystem konnte nicht initialisiert werden. Druckfunktion nicht verfügbar." + fi +} & + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_sound.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_sound.inc new file mode 100644 index 00000000..c6cece3d --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_sound.inc @@ -0,0 +1,79 @@ +#!/bin/bash +# ^-- Add shebang even though it's sourced so vim highlights bash specific features properly +######################## +# Include: Setup sound # +######################## + +writelog "Starting sound setup ..." + +unset VOL +if [ -r "/run/hwinfo" ] && source "/run/hwinfo"; then + # On startup, the volume of Master, PCM, Speaker, etc. will be set to 100% + # Some hardware with builtin speakers might be a bit too loud then, so you can + # define an exception table here. Array key is "Manufacturer//Model" + declare -A VOLUME_EXCEPTIONS + VOLUME_EXCEPTIONS["Hewlett-Packard//HP Compaq 8200 Elite CMT PC"]="85%" # This is bwPC3 + # Read + VOL=${VOLUME_EXCEPTIONS["${HW_MANUF}//${HW_MODEL}"]} +fi + +# Default to maximum volume +if [ -z "$VOL" ]; then + VOL="100%" +fi + +if true; then + # detecting which card is to be used + writelog --quiet "Detecting which sound card to use ..." + PROC="/proc/asound/cards" + if [ ! -r "$PROC" ]; then + writelog --quiet "'${PROC}' not found or not readable." + SOUND_CARD_INDEX=0 + SOUND_CARD_COUNT=1 + else + # Try to filter HDMI cards first + SOUND_CARD_INDEX=$(grep -v -i 'HDMI' "${PROC}" | grep -E -o '^[[:space:]]{0,2}[0-9]+[[:space:]]+' | head -n 1) + # If empty, try again with all + [ -z "${SOUND_CARD_INDEX}" ] && SOUND_CARD_INDEX=$(cat "${PROC}" | grep -E -o '^[[:space:]]{0,2}[0-9]+[[:space:]]+' | head -n 1) + if [ -z "${SOUND_CARD_INDEX}" ]; then + writelog --quiet "No sound card found." + SOUND_CARD_INDEX=0 + fi + SOUND_CARD_COUNT=$(grep -E '^[[:space:]]{0,2}[0-9]+[[:space:]]+' "${PROC}" | wc -l) + fi + + SOUND_CARD_INDEX="$(grep -E -o '[0-9]+' <<<$SOUND_CARD_INDEX)" + writelog --quiet "Detected sound card index is: $SOUND_CARD_INDEX" + writelog --quiet "Sound card count: $SOUND_CARD_COUNT" + + # Adjust sound volume (playback)... Random mixer names we have encountered during testing + writelog --quiet "Setting up volume..." + ( + amixer -q -c "$SOUND_CARD_INDEX" sset 'Master' "$VOL" unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'PCM' "100%" unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'CD' "100%" unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Headphone' "100%" unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Front' "100%" unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Speaker' "100%" unmute + # Recording. It seems that (most) devices need the volume set to 0, so you + # don't hear your own mic input, but should be unmuted. Also on some cards, + # you need to set the cap option on the mic you want to use, while other cards + # will just ignore that option. + # Plus, most cards have a Capture mixer, which needs to be set to cap too, and + # have its volume turned up. (There'll probably be some cards that need yet + # another setup, but this works for now on 4 tested cards) + amixer -q -c "$SOUND_CARD_INDEX" sset 'Rear Mic Boost' "50%" cap unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Rear Mic' "0%" cap unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Front Mic Boost' "50%" cap unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Front Mic' "0%" cap unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Mic Boost' "50%" cap unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Mic' "0%" cap unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Capture' "100%" cap unmute + amixer -q -c "$SOUND_CARD_INDEX" sset 'Input Source' 'Mic' + amixer -q -c "$SOUND_CARD_INDEX" sset 'Input Source' 'Front Mic' # Let's hope nobody uses rear mic... + # fix random static noise when starting vmplayer when module snd_pcsp (not pcspkr) is loaded + amixer -q -c pcsp sset Master "0%" mute 2>/dev/null >&2 + ) 2>&1 | grep -v 'amixer: Unable to find' + writelog --quiet "Done setting up volume." +fi >> "${LOGFILE}" 2>&1 # Don't pipe here since it would spawn a subshell so all variable modifications would be lost + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_virtual_floppy.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_virtual_floppy.inc new file mode 100644 index 00000000..d9ae052c --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_virtual_floppy.inc @@ -0,0 +1,101 @@ +#!/bin/bash +############################################## +# Include: Setup virtual floppy for drive b: # +############################################## + +declare -rg FLOPPYIMG="${TMPDIR}/floppy.img" +declare -rg TMPHOME="${HOME}" +declare -rg RUNSCRIPT="${TMPDIR}/runscript.tmp" + +wget -T 6 -O "${RUNSCRIPT}" "${SLX_VMCHOOSER_BASE_URL}/lecture/${IMGUUID}/runscript" > /dev/null & +WGET=$! + +dd "if=/dev/zero" "of=${FLOPPYIMG}" count=1440 bs=1024 +chmod 0600 "${FLOPPYIMG}" +mkfs.fat "${FLOPPYIMG}" || mkfs.vfat "${FLOPPYIMG}" || mkdosfs "${FLOPPYIMG}" + +# Create file with resolution information etc. +. "/opt/openslx/inc/shares" +if [ -z "$SHARE_REMAP_MODE" ]; then + SHARE_REMAP_MODE_INI="0" + SHARE_REMAP_MODE="3" +else + SHARE_REMAP_MODE_INI="$SHARE_REMAP_MODE" +fi +[ -z "$SHARE_CREATE_MISSING_REMAP" ] && SHARE_CREATE_MISSING_REMAP="1" +declare -rg RESOLUTION=$(xrandr | grep -o -E 'connected\s*(primary)?\s*[0-9]+x[0-9]+\+0\+0' \ + | grep -o -E -m1 '[0-9]+x[0-9]+') + +# Legacy: HOSTRES.TXT +cat > "${TMPDIR}/HOSTRES.TXT" <<-HIER +${RESOLUTION} +HIER + +# Create file for network shares to mount +declare -rg SHARES="${TMPDIR}/shares.dat" +touch "${SHARES}" +chmod 0600 "${SHARES}" +if ! pwdaemon --query "${TMPHOME}/.pwsocket" > "${SHARES}"; then + slxlog "virt-pwdaemon" "Could not start pwdaemon" +else + sed -i 's/^/192.168.101.1\t/' "${SHARES}" # TODO: Depending on nettype (in case we have != nat some day) + if [ "${SHARE_REMAP_MODE}" = 1 -o "${SHARE_REMAP_MODE}" = 2 ] && [ -e "${TMPHOME}/.home" ]; then + NETHOME=$(cat "${TMPHOME}/.home") + [ -z "$SHARE_HOME_DRIVE" ] && SHARE_HOME_DRIVE="H:" + # Tab between items, so spaces can be used! + echo "${NETHOME} ${SHARE_HOME_DRIVE} Home-Verzeichnis" >> "${SHARES}" + fi + for VAR in ${!SHARE_LINE_*}; do + echo "${!VAR}" >> "${SHARES}" + done +fi + +wait "$WGET" + +# Check downloaded runscript, handle extension marker +EXT= +if [ -s "$RUNSCRIPT" ]; then + EXT=$(head -n 1 "$RUNSCRIPT" | grep -o -i '^EXT=.*$' | cut -d '=' -f 2-) + [ -n "$EXT" ] && [ "x${EXT:0:1}" != "x." ] && EXT=".$EXT" +fi + +# Write info file +UNAME= +[ -s "${HOME}/.account" ] && UNAME=$(cat "${HOME}/.account") +[ -z "${UNAME}" ] && UNAME=$(whoami) +cat > "${TMPDIR}/openslx.ini" <<-HIER +[openslx] +username=${UNAME} +resolution=${RESOLUTION} +createMissingRemap=${SHARE_CREATE_MISSING_REMAP} +remapMode=${SHARE_REMAP_MODE_INI} +homeDrive=${SHARE_HOME_DRIVE} +scriptExt=${EXT} + +[remap] +documents=${SHARE_DOCUMENTS} +downloads=${SHARE_DOWNLOADS} +desktop=${SHARE_DESKTOP} +media=${SHARE_MEDIA} +other=${SHARE_OTHER} +HIER + +# Copy all them there filez into floppy image +mcopy -i "${FLOPPYIMG}" "${TMPDIR}/openslx.ini" "${TMPDIR}/HOSTRES.TXT" "${SHARES}" "::/" +mcopy -i "${FLOPPYIMG}" "$VMCHOOSER_DIR/data/openslx.exe" "::/" +# Copy guest configuration (with added information) config.xml to be accessed +# via virtual floppy +mcopy -i "${FLOPPYIMG}" "$xmlfile" "::/config.xml" + +# Copying linux directory: +mcopy -s -i "${FLOPPYIMG}" "$VMCHOOSER_DIR/data/linux" "::/" + +# User supplied runscript +if [ -n "$EXT" ]; then + sed -i '1d' "${RUNSCRIPT}" + mcopy -i "${FLOPPYIMG}" "${RUNSCRIPT}" "::/runscript${EXT}" +fi + +rm -f -- "${SHARES}" "${TMPDIR}/openslx.ini" "${TMPDIR}/HOSTRES.TXT" +unset SHARES VAR NETHOME UNAME + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_vm_hypervisor.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_vm_hypervisor.inc new file mode 100644 index 00000000..7709a85d --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_vm_hypervisor.inc @@ -0,0 +1,34 @@ +########################################################################## +# Include: Setup virtual machine hypervisor via vm-specific include file # +########################################################################## + +# Get all virtual machine specific stuff from the respective include file +if [ ! -e "$VMCHOOSER_DIR/$PLUGIN_ID/run-virt.include" ] ; then + slxlog "virt-plugin-missing" "Could not find run-virt.include for $PLUGIN_ID ($VMCHOOSER_DIR/$PLUGIN_ID/run-virt.include)" + writelog "Failed because of missing ${PLUGIN_ID} plugin." + error_user "Konnte den Virtualisierer '$PLUGIN_ID' nicht finden. Starten der Virtuellen Maschine fehlgeschlagen. + Starten Sie den Computer neu und wenden Sie sich an den Support, wenn das Problem weiterhin besteht." + cleanexit 1 +fi + +self="${PLUGIN_ID}" + +if ! bash -n "$VMCHOOSER_DIR/$PLUGIN_ID/run-virt.include"; then + slxlog "virt-plugin-syntax" "run-virt.include for $PLUGIN_ID contains syntax errors (bash -n run-virt.include failed)" + writelog "Erroneous run-virt.include for $PLUGIN_ID (syntax check)" + error_user "Das Start-Script für den Virtualisierer '$PLUGIN_ID' ist fehlerhaft. + Starten Sie den Computer neu und wenden Sie sich an den Support, wenn das Problem weiterhin besteht." + cleanexit 1 +fi + +setup_vm_commandline () { + # Now including the hypervisor specific include file: + if ! source "$VMCHOOSER_DIR/$PLUGIN_ID/run-virt.include"; then + slxlog "virt-plugin-error" "run-virt.include for $PLUGIN_ID could not be sourced properly." + writelog "Erroneous run-virt.include for ${PLUGIN_ID}? Source returned != 0" + error_user "Das Start-Script für den Virtualisierer '$PLUGIN_ID' hat einen fehlercode zurückgegeben. + Starten Sie den Computer neu, falls es beim Ausführen der VM zu Problemen kommt + und wenden Sie sich an den Support, wenn das Problem weiterhin besteht." + fi +} + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/start_windowmanager.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/start_windowmanager.inc new file mode 100644 index 00000000..da43f341 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/start_windowmanager.inc @@ -0,0 +1,27 @@ +#################################################### +# Include: Start windowmanager for easier handling # +#################################################### + +# Some problems may arise with windows opening in background when +# using eg. vmware without a window manager. + +FOUND_WM= +for dm in openbox kwin xfwm4 metacity blackbox twm fvwm2 ; do + if which $dm >/dev/null 2>&1 ; then + if [ "$dm" = "fvwm2" ] ; then + echo "EdgeScroll 0 0" > ${redodir}/fvwm + writelog "Starting fvwm2." + fvwm2 -f ${redodir}/fvwm >/dev/null 2>&1 & + else + writelog "Starting ${dm}." + $dm >/dev/null 2>&1 & + fi + FOUND_WM=1 + break + fi +done + +if [ -z "$FOUND_WM" ]; then + slxlog "virt-windowmanager" "Could not find any window manager to use!" + notify_user "Konnte keinen Window Manager finden. (Das ist schlecht!)" +fi diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/usb_detector.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/usb_detector.inc new file mode 100644 index 00000000..a2d442e4 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/usb_detector.inc @@ -0,0 +1,77 @@ +# Helper function that will scan /dev/bus/usb for devices matching specific classes +# and then output the corresponding device ids. This can be used for selective +# handover of devices to a virtual machine + +declare -rg PASSTHROUGH_USB_DEVICES="2 0:5 0:6 0:7 0:14 0:16 0:17 239" + +# $1: expression to fill with device information. +# valid placeholders are: +# %VENDOR% - device vendor id +# %PRODUCT% - device product id +# $2-n: device classes to include in output +get_usb_devices_int() { + [ -z "$TMPDIR" ] && TMPDIR="/tmp" + local EXP=$1 + shift + if [ -z "$EXP" ]; then + writelog --quiet "No ouput expression template passed to get_usb_devices" + cleanexit 1 + fi + if [ $# -eq 0 ]; then + writelog --quiet "No device classes given to get_usb_devices" + cleanexit 1 + fi + local MATCH=';' + while [ $# -gt 0 ]; do + MATCH+="$1;" + [[ "$1" != *:* ]] && MATCH+="0:$1;" + shift + done + local dev= + local key value trailing + trailing= + local tmp="${TMPDIR}/lsusb.$$.$RANDOM" + for dev in /dev/bus/usb/*/*; do + if ! lsusb -D "$dev" > "$tmp" 2>/dev/null; then + writelog --quiet "Cannot lsusb $dev" + continue + fi + local DC= + local OK= + local VENDOR= + local PRODUCT= + while read -r key value trailing || [ -n "$key" ]; do + if [[ "$key" == "idVendor" ]]; then + [[ "$value" == 0x* ]] && VENDOR="${value:2}" + elif [[ "$key" == "idProduct" ]]; then + [[ "$value" == 0x* ]] && PRODUCT="${value:2}" + elif [ -z "$DC" ]; then + # No bDeviceClass seen yet + if [[ "$key" == "bDeviceClass" ]]; then + DC="$value" + [[ "$MATCH" == *";${DC};"* ]] && OK=yo + fi + else + # #DeviceClass is generic, look at sub class + if [[ "$key" == "bInterfaceClass" ]]; then + [[ "$MATCH" == *";${DC}:${value};"* ]] && OK=yo + fi + fi + if [ -n "$OK" -a -n "$VENDOR" -a -n "$PRODUCT" ]; then + echo "$EXP" | sed "s/%VENDOR%/${VENDOR}/g;s/%PRODUCT%/${PRODUCT}/g" + break + fi + done < "$tmp" + done + rm -f -- "$tmp" +} + +get_usb_devices() { + if which lsusb 2>/dev/null >&2 && lsusb --help 2>&1 | grep -q -- '-D' 2>/dev/null; then + [ $# -eq 1 ] && set -- "$1" $PASSTHROUGH_USB_DEVICES # no quotes here! + get_usb_devices_int "$@" | sort -u + else + writelog --quiet "Cannot scan usb bus: lsusb not found or doesn't support -D" + fi +} + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/vmchooser_runvirt_functions.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/vmchooser_runvirt_functions.inc new file mode 100644 index 00000000..ca475da0 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/vmchooser_runvirt_functions.inc @@ -0,0 +1,107 @@ +####################################################### +# Include: Set functions needed by vmchooser-run_virt # +####################################################### + +# function to write to stdout and logfile +writelog() { + local DATE=$(date +%Y-%m-%d-%H-%M-%S) + # write to stdout? + if [ "x$1" = "x--quiet" ]; then + shift + else + echo -e "$DATE: $@" + fi + # log into file + echo -e "$DATE: $@" >> "${LOGFILE}" +} + +notify_user() { + local TOPIC="$1" + shift + notify-send -u normal "$TOPIC" "$@" + writelog "Notify: **${TOPIC}**: $*" +} + +error_user() { + local TOPIC="$1" + shift + local MSG TITLE BODY + if [ $# -gt 0 ]; then + MSG=" $TOPIC +$*" + TITLE="$TOPIC" + BODY="$*" + else + MSG="$TOPIC" + TITLE="ERROR" + BODY="$TOPIC" + fi + # Zenity should yield the nicest result + zenity --error --title "$TITLE" --text "$BODY" && return + # QnD abuse printergui for error message as it's blocking + /opt/openslx/cups/printergui --error "$MSG" && return + # printergui might not exist, try fallback here + # unfortunately, i can only think of notify+sleep right now + notify-send -u critical "$TITLE" "$BODY" + sleep 10 +} + +# Clean exit will be called at the end of vmchooser-run_virt +cleanexit() { + sleep 1 + # Ummount dnbd3-fuse + if [ -n "$dnbd3_fuse_mount_point" ] && [ -e "$dnbd3_fuse_mount_point/img" ]; then + for timeout in 1 1 1 FAIL; do + fusermount -u "$dnbd3_fuse_mount_point" && break + writelog "dnbd3 still busy...." + [ "$timeout" = "FAIL" ] && break + sleep "$timeout" + done + fi + # Kill LPD + [ -n "${PID_LPD}" ] && kill "${PID_LPD}" + + # If we're not in debug mode, remove all temporary files + if [ -n "${TMPDIR}" -a -z "$SLX_DEBUG" ]; then + rm -rf -- "${TMPDIR}" + fi + + [ $# -gt 0 ] && exit "$1" + exit 129 # No exit code was given :/ +} + +rv_clean_string() { + if [ "$#" -ge 1 ]; then + echo "$@" | tr '[A-Z]' '[a-z]' | tr -d -c '[a-z0-9\-]' + else + tr '[A-Z]' '[a-z]' | tr -d -c '[a-z0-9\-]' + fi +} + +# Check if the given variables are set (empty or not) +isset() { + while [ $# -gt 0 ]; do + [ -z "${!1+x}" ] && return 1 + shift + done + return 0 +} + +# Check if the given variables are not empty +notempty() { + while [ $# -gt 0 ]; do + [ -z "${!1}" ] && return 1 + shift + done + return 0 +} + +## +# Extract given xpath from given xml file +# e.g.: xmlextract '//node/nestednode/@attribute' "$file" +# @param +# @return Plain text, UTF-8 +xmlextract() { + xmlstarlet sel -T -E utf-8 -t -v "$1" "$2" +} + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/scripts/set-firewall b/core/modules/run-virt/data/opt/openslx/vmchooser/scripts/set-firewall new file mode 100644 index 00000000..2773150c --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/scripts/set-firewall @@ -0,0 +1,130 @@ +#!/bin/bash + +# Do not rename/move this script, or change fwtool.c accordingly + +[ "$UID" = "0" ] || exit 1 + +declare -rg RULES=$(mktemp) + +[ -n "$RULES" ] || exit 2 + +[ -n "$1" ] || exit 3 + +[ "${#1}" -ge 10 ] || exit 4 +[ "${#1}" -lt 40 ] || exit 5 + +. /opt/openslx/config + +for TOOL in iptables ip6tables; do + $TOOL -w -F runvirt-INPUT || $TOOL -w -N runvirt-INPUT + $TOOL -w -F runvirt-OUTPUT || $TOOL -w -N runvirt-OUTPUT + + if ! $TOOL -w -C INPUT -i br0 -j runvirt-INPUT; then + $TOOL -w -A INPUT -i br0 -j runvirt-INPUT + fi + if ! $TOOL -w -C OUTPUT -o br0 -j runvirt-OUTPUT; then + $TOOL -w -A OUTPUT -o br0 -j runvirt-OUTPUT + fi + if ! $TOOL -w -C FORWARD -i br0 -j runvirt-INPUT; then + $TOOL -w -A FORWARD -i br0 -j runvirt-INPUT + fi + if ! $TOOL -w -C FORWARD -o br0 -j runvirt-OUTPUT; then + $TOOL -w -A FORWARD -o br0 -j runvirt-OUTPUT + fi + $TOOL -A runvirt-INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT + $TOOL -A runvirt-OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT +done + +declare -rg AUTORULES=$(mktemp) + +add_ips () { + # add_ips "IN/OUT" "IP1 IP2 IPn" "PORT" "ACCEPT/REJECT" + local IP + [ -z "$1" -o -z "$2" -o -z "$3" -o -z "$4" ] && return 1 + for IP in $2; do + echo "$1 $IP $3 $4" >> "${AUTORULES}" + done +} + +add_ips "IN" "127.0.0.0/8" 0 "ACCEPT" +add_ips "OUT" "127.0.0.0/8" 0 "ACCEPT" +add_ips "OUT" "$SLX_DNS" 53 "ACCEPT" +add_ips "OUT" "$SLX_DNBD3_SERVERS" 5003 "ACCEPT" +add_ips "OUT" "$SLX_KCL_SERVERS $SLX_SERVER_IP" 0 "ACCEPT" + +if [ -n "$SLX_VM_NFS" ]; then + IP= + if [ "${SLX_VM_NFS:0:2}" = '//' ]; then + IP=${SLX_VM_NFS:2} + IP=${IP%%/*} + else + IP=${SLX_VM_NFS%%:*} + fi + [ -n "$IP" ] && add_ips "OUT" "$IP" 0 "ACCEPT" +fi + +sort -u "${AUTORULES}" > "${RULES}" + +wget -T 6 -O - "${SLX_VMCHOOSER_BASE_URL}/lecture/$1/netrules" >> "${RULES}" 2> "${AUTORULES}" +RET=$? + +if [ "$RET" != "0" ]; then + echo "wget exit code: $RET :-(" + grep -q "ERROR 404" "${AUTORULES}" && exit 0 + exit 6 +fi + +declare -rg V4='^[0-9]+(\.[0-9]+)*(/[0-9]+)?$' +declare -rg V6='^([0-9a-fA-F]+|:)(:+[0-9a-fA-F]*)*(/[0-9]+)?$' + +while read -r DIR DEST PORT ACTION GARBAGE || [ -n "$DIR" ]; do + if [ -z "$DEST" -o -z "$PORT" -o -z "$ACTION" ]; then + echo "Invalid rule: '$DIR $DEST $PORT $ACTION'" + continue + fi + IPLINE1=" -w" + IPLINE2= + if [ "$DIR" = "IN" ]; then + IPLINE1+=" -A runvirt-INPUT" + elif [ "$DIR" = "OUT" ]; then + IPLINE1+=" -A runvirt-OUTPUT" + else + continue + fi + if ! [[ $PORT =~ ^[0-9]+$ ]] || [ "$PORT" -gt 65535 ]; then + echo "Invalid port: '$PORT'" + continue + fi + if [ "$DEST" != "*" ]; then + if [ "$DIR" = "OUT" ]; then + IPLINE1+=" -d $DEST" + else + IPLINE1+=" -s $DEST" + fi + fi + if [ "$PORT" != 0 ]; then + IPLINE2+=" --dport $PORT" + fi + IPLINE2+=" -j $ACTION" + # IPv6? + if ! [[ $DEST =~ $V4 ]]; then + if [ "$PORT" = 0 ]; then + ip6tables $IPLINE1 $IPLINE2 + else + ip6tables $IPLINE1 -p tcp $IPLINE2 + ip6tables $IPLINE1 -p udp $IPLINE2 + fi + fi + # IPv4 + if ! [[ $DEST =~ $V6 ]]; then + if [ "$PORT" = 0 ]; then + iptables $IPLINE1 $IPLINE2 + else + iptables $IPLINE1 -p tcp $IPLINE2 + iptables $IPLINE1 -p udp $IPLINE2 + fi + fi +done < "$RULES" + +exit 0 + diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/vmchooser-run_virt b/core/modules/run-virt/data/opt/openslx/vmchooser/vmchooser-run_virt new file mode 100755 index 00000000..b945cca2 --- /dev/null +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/vmchooser-run_virt @@ -0,0 +1,119 @@ +#!/bin/bash +# Full bash required +# ----------------------------------------------------------------------------- +# Copyright (c) 2007..2010 - RZ Uni FR +# Copyright (c) 2007..2013 - OpenSLX GmbH +# +# This program is free software distributed under the GPL version 2. +# See http://openslx.org/COPYING +# +# If you have any feedback please consult http://openslx.org/feedback and +# send your suggestions, praise, or complaints to feedback@openslx.org +# +# General information about OpenSLX can be found at http://openslx.org/ +# ----------------------------------------------------------------------------- +# run-virt.sh +# - This is the generic wrapper for the several virtualization solutions. +# The idea is to setup a set of variables used by at least two different +# tools and then include the specific plugin which configures the speci- +# fied virtualization tool. +################################################################################ + +declare -rg RUNVIRTINCLUDEDIR=/opt/openslx/vmchooser/run-virt-includes +declare -rg xmlfile="$1" + +# Functions needed by vmchooser-run_virt (writelog(), cleanexit(), rv_clean_string()) +if ! source "${RUNVIRTINCLUDEDIR}/vmchooser_runvirt_functions.inc"; then + slxlog "run-virt" "Could not source ${RUNVIRTINCLUDEDIR}/vmchooser_runvirt_functions.inc" + exit 1 +fi + +trap 'trap "" SIGINT SIGTERM; cleanexit' SIGINT SIGTERM + +# Define default dirs / get configs +source "${RUNVIRTINCLUDEDIR}/set_runvirt_variables.inc" + +# Read needed variables from XML file +source "${RUNVIRTINCLUDEDIR}/get_xml_file_variables.inc" + +# Download meta data from server (e.g. vmx for vmware) +source "${RUNVIRTINCLUDEDIR}/download_vm_metadata.inc" + +if ! isset IMGUUID TMPCONFIG TMPDIR USER; then + slxlog "run-virt" "Internal sanity check failed: One of IMGUUID TMPCONFIG TMPDIR USER is not set." + cleanexit 1 +fi + +if [ "$LEGACY" ]; then + + # No longer supported - yay + + error_user "Legacy Mode" " +Die gewählte VM ist eine 'Legacy VM', für die unvollständige +Metadaten auf dem bwLehrpool-Server hinterlegt sind. Diese +werden nicht mehr unterstützt. Um diese VM weiterhin nutzen +zu können, muss sie mittels der bwLehrpool-Suite heruntergeladen, +einmal gebootet, und wieder hochgeladen werden. +(Bei der Gelegenheit könnten z.B. auch gleich anfallende Updates +eingespielt werden.) +" + cleanexit 1 + + # End legacy warning +fi + +# Proper meta data received - proceed normally + +# Helper that looks for virtualizer-specific include, show error to user if not found +source "${RUNVIRTINCLUDEDIR}/setup_vm_hypervisor.inc" + +# For scanning for certain usb classes +source "${RUNVIRTINCLUDEDIR}/usb_detector.inc" + +# Firewall +source "${RUNVIRTINCLUDEDIR}/setup_firewall.inc" || writelog "Could not source setup_firewall" +setup_firewall || writelog "Could not run setup_firewall" + +# Sound setup +source "${RUNVIRTINCLUDEDIR}/setup_sound.inc" + +# Declaration of hardware relatedt variables +source "${RUNVIRTINCLUDEDIR}/set_runvirt_hardware_variables.inc" + +# Start printer daemon +source "${RUNVIRTINCLUDEDIR}/setup_printer_lpd.inc" + +# Setup virtual floppy b: for windows guests with config.xml, openslx.exe etc. +source "${RUNVIRTINCLUDEDIR}/setup_virtual_floppy.inc" + +# Try to use dnbd3 to access the image, nfs/cifs fallback +source "${RUNVIRTINCLUDEDIR}/setup_image_access.inc" + +# Window manager required for handling of popups etc. +source "${RUNVIRTINCLUDEDIR}/start_windowmanager.inc" + +# Source run-virt.include of virtualizer +setup_vm_commandline + +# It should have set this variable if all went well +if [ -z "${VIRTCMD}" ]; then + error_user "Fehler beim Starten der VM-Sitzung" " +Das Start-Script für den Virtualisierer $PLUGIN_ID hat kein Kommando +zum Starten der Sitzung definiert. Kann Sitzung nicht initialisieren." + slxlog "virt-plugin-error" "run-virt.include for $PLUGIN_ID did not set VIRTCMD" + cleanexit 1 +fi + +writelog "VM command: eval ${VIRTCMD} ${VIRTCMDOPTS}" +# This will start the VM +eval ${VIRTCMD} ${VIRTCMDOPTS} + +writelog "Virtualizer exited. Bye." + +# Postrun for commands after virtualization finishes +if [ -n "${POSTRUN}" ]; then + eval ${POSTRUN} >/dev/null 2>&1 +fi + +cleanexit 0 + diff --git a/core/modules/run-virt/fwtool/main.c b/core/modules/run-virt/fwtool/main.c new file mode 100644 index 00000000..9e272384 --- /dev/null +++ b/core/modules/run-virt/fwtool/main.c @@ -0,0 +1,32 @@ +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +int main(int argc, char **argv) +{ + if (argc < 2) { + puts("Nee\n"); + return 1; + } + char * const nargv[] = { + "bash", + "/opt/openslx/vmchooser/scripts/set-firewall", + argv[1], + 0 + }; + char * const nenv[] = { + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin", + "HOME=/root", + "LC_ALL=C", + "LANG=C", + 0 + }; + + setresuid(0, 0, 0); + setregid(0, 0); + + execve("/bin/bash", nargv, nenv); +} + diff --git a/core/modules/run-virt/module.build b/core/modules/run-virt/module.build index 26762bca..56afd839 100644 --- a/core/modules/run-virt/module.build +++ b/core/modules/run-virt/module.build @@ -8,9 +8,13 @@ build () { rm -f -- "$COPYLIST" list_packet_files > "$COPYLIST" tarcopy "$(cat "$COPYLIST" | sort -u)" "${MODULE_BUILD_DIR}" + # Compile pwdaemon + mkdir -p "${MODULE_BUILD_DIR}/opt/openslx/bin" + gcc -std=gnu99 -o "${MODULE_BUILD_DIR}/opt/openslx/bin/pwdaemon" -Os "${MODULE_DIR}/pw_daemon.c" || perror "Could not compile the pwdaemon" + gcc -std=gnu99 -o "${MODULE_BUILD_DIR}/opt/openslx/bin/slxfwtool" -Os "${MODULE_DIR}/fwtool/main.c" || perror "Could not compile slxfwtool" } post_copy() { - : + chmod +s "${TARGET_BUILD_DIR}/opt/openslx/bin/slxfwtool" || perror "Could not set suid bit on slxfwtool" } diff --git a/core/modules/run-virt/module.conf b/core/modules/run-virt/module.conf index bd24ba58..cc1b34a6 100644 --- a/core/modules/run-virt/module.conf +++ b/core/modules/run-virt/module.conf @@ -1,4 +1,8 @@ REQUIRED_BINARIES=" lsusb + mcopy + pwdaemon + slxfwtool + xmlstarlet " diff --git a/core/modules/run-virt/module.conf.ubuntu b/core/modules/run-virt/module.conf.ubuntu index b285210b..b6008fa0 100644 --- a/core/modules/run-virt/module.conf.ubuntu +++ b/core/modules/run-virt/module.conf.ubuntu @@ -1,7 +1,11 @@ REQUIRED_INSTALLED_PACKAGES=" usbutils + mtools + xmlstarlet " REQUIRED_CONTENT_PACKAGES=" usbutils + mtools + xmlstarlet " diff --git a/core/modules/run-virt/pw_daemon.c b/core/modules/run-virt/pw_daemon.c new file mode 100644 index 00000000..768a5b00 --- /dev/null +++ b/core/modules/run-virt/pw_daemon.c @@ -0,0 +1,315 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <linux/random.h> +#include <errno.h> +#include <unistd.h> +#include <time.h> +#include <fcntl.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#include <sys/prctl.h> +#include <sys/un.h> + +static const ssize_t KEYLEN = 16; + +static pid_t udpPid = -1; +static char *username = NULL; +static uint8_t *passwordEnc = NULL; +static size_t passwordLen = 0; +static uint8_t *key1 = NULL, *key2 = NULL; +static char *key1s = NULL, *key2s = NULL; + +static int mode_daemon(); +static int mode_query(const char *socketPath); +static void sig_handler(int sig); +static int setup_vars(const char *envuser, const char *envpass); +static uint8_t* keygen(); +static char* bin2hex(uint8_t* bin, size_t len); +static uint8_t* xorString(const char* inputText, const uint8_t* key); +static int init_udp(); + +int main(int argc, char **argv) +{ + if (argc > 1 && strcmp(argv[1], "--daemon") == 0) { + return mode_daemon(); + } else if (argc > 2 && strcmp(argv[1], "--query") == 0) { + return mode_query(argv[2]); + } + fprintf(stderr, "Invalid call. Use --daemon or --query\n"); + return 1; +} + +static int mode_query(const char *socketPath) +{ + int fd; + struct sockaddr_un remote; + struct timeval tv; + char buffer[200]; + ssize_t ret; + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + perror("Cannot create unix socket for connecting"); + return 1; + } + memset(&remote, 0, sizeof(remote)); + remote.sun_family = AF_UNIX; + strncpy(remote.sun_path, socketPath, sizeof(remote.sun_path)-1); + tv.tv_sec = 2; + tv.tv_usec = 0; + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + if (connect(fd, (struct sockaddr*)&remote, sizeof(remote)) == -1) { + perror("Cannot connect to pw daemon"); + return 1; + } + if (write(fd, "GET", 3) == -1) { + perror("Writing to pw daemon failed"); + return 1; + } + ret = read(fd, buffer, sizeof(buffer)-1); + if (ret == -1) { + perror("Reading from pw daemon failed"); + return 1; + } + if (ret < 1 || (size_t)ret > sizeof(buffer)-1) { + fprintf(stderr, "Reply from pw daemon has invalid length\n"); + return 1; + } + if (buffer[ret-1] != '\n') { + fprintf(stderr, "Corrupted reply received from pw daemon\n"); + return 1; + } + buffer[ret] = '\0'; + printf("%s", buffer); + return 0; +} + +static int mode_daemon() +{ + int listenFd, udpPort = -1; + struct sockaddr_un addr; + struct sigaction sig; + const char *envuser = getenv("USERNAME"); + const char *envpass = getenv("PASSWORD"); + const char *pwsocket = getenv("PWSOCKET"); + memset(&addr, 0, sizeof(addr)); + memset(&sig, 0, sizeof(sig)); + if (envuser == NULL) { + fprintf(stderr, "USERNAME not set\n"); + return 1; + } + if (envpass == NULL) { + fprintf(stderr, "PASSWORD not set\n"); + return 1; + } + if (pwsocket == NULL) { + fprintf(stderr, "PWSOCKET not set\n"); + return 1; + } + if (setup_vars(envuser, envpass) == -1) { + fprintf(stderr, "Error setting up variables\n"); + return 1; + } + listenFd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (listenFd == -1) { + perror("Could not create unix socket"); + return 1; + } + // Change permissions before bind, so it will be created with + // the right ones right away + if (fchmod(listenFd, S_IRUSR | S_IWUSR) == -1) { + perror("Cannot set permissions on socket fd prior to binding"); + return 1; + } + remove(pwsocket); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, pwsocket, sizeof(addr.sun_path)-1); + if (bind(listenFd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + perror("Could not bind unix socket"); + return 1; + } + if (listen(listenFd, 10) == -1) { + perror("Cannot listen on unix socket"); + return 1; + } + // Mainloop + sig.sa_handler = &sig_handler; + sigaction(SIGCHLD, &sig, NULL); + for (;;) { + struct sockaddr_un remote; + socklen_t len = sizeof(remote); + int fd = accept(listenFd, (struct sockaddr*)&remote, &len); + if (fd != -1) { + if (udpPort == -1) { + udpPort = init_udp(); + } + // Success, handle client + pid_t child = fork(); + if (child == 0) { + // This is the child + ssize_t ret; + char buffer[200]; + ret = read(fd, buffer, sizeof(buffer)); + if (ret >= 3 && strncmp(buffer, "GET", 3) == 0) { + snprintf(buffer, sizeof(buffer), "%d\t%s\t%s\t%s\n", udpPort, key1s, key2s, username); + ret = write(fd, buffer, strlen(buffer)); + } + close(fd); + return 0; + } else { + // Parent, close child fd + close(fd); + } + } else { + // Error? + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR || errno == ECONNABORTED) + continue; + perror("Fatal accept error, bailing out"); + return 1; + } + } + return 0; +} + +static void sig_handler(int sig) +{ + pid_t p; + int status = sig; // Mute unused warning + while ((p = waitpid(-1, &status, WNOHANG)) > 0) { + if (p == udpPid) { + fprintf(stderr, "UDP listener died!\n"); + exit(1); + } + } +} + +static int setup_vars(const char *envuser, const char *envpass) +{ + srand((unsigned int)getpid() ^ (unsigned int)time(NULL)); + key1 = keygen(); + key2 = keygen(); + key1s = bin2hex(key1, (size_t)KEYLEN); + key2s = bin2hex(key2, (size_t)KEYLEN); + username = strdup(envuser); + passwordEnc = xorString(envpass, key2); + passwordLen = strlen(envpass) + 2; // +2 for 2byte length prefix + if (key1s == NULL || key2s == NULL || username == NULL || passwordEnc == NULL) { + return -1; + } + return 0; +} + +static uint8_t* keygen() +{ + ssize_t done = 0, ret; + uint8_t *key = malloc(KEYLEN); + int entropy; + int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); + if (fd != -1) { + if (ioctl(fd, RNDGETENTCNT, &entropy) == 0 && entropy > 0) { //Make sure we opened a random device + while (done < KEYLEN) { + ret = read(fd, key + done, (size_t)(KEYLEN - done)); + if (ret == -1) { + if (errno == EINTR) + continue; + break; + } + if (ret == 0) + break; + done += ret; + } + } + close(fd); + fprintf(stderr, "Got %d bytes from urandom\n", (int)done); + } + while (done < KEYLEN) { + key[done++] = (char)(rand() & 0xff); + } + return key; +} + +static uint8_t* xorString(const char* inputText, const uint8_t* key) +{ + uint8_t *text = (uint8_t*)inputText; + size_t len = strlen(inputText); + size_t i; + uint8_t *retval = malloc(len + 2); + uint8_t *ptr = retval + 2; + retval[0] = (uint8_t)(len & 0xff00) >> 8; + retval[1] = (uint8_t)(len & 0xff); + for (i = 0; i < len; ++i) { + ptr[i] = text[i] ^ key[i % KEYLEN]; + } + return retval; +} + +static char* bin2hex(uint8_t* bin, size_t len) +{ + static const char hexconvtab[] = "0123456789abcdef"; + char *retval = malloc(len * 2 + 1); + size_t i; + for (i = 0; i < len; ++i) { + retval[i*2] = hexconvtab[bin[i] >> 4]; + retval[i*2+1] = hexconvtab[bin[i] & 0xf]; + } + retval[i*2] = '\0'; + return retval; +} + +static int init_udp() +{ + uint16_t port = 0; + int fd; + int tries = 0; + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) { + perror("Cannot create udp socket"); + return -1; + } + for (;;) { + port = (uint16_t)(40000 + rand() % 20000); + struct sockaddr_in local; + local.sin_family = AF_INET; + local.sin_port = htons((uint16_t)port); + local.sin_addr.s_addr = INADDR_ANY; + if (bind(fd, (struct sockaddr*)&local, sizeof(local)) == -1) { + if (++tries > 100) { + perror("Cannot bind udp socket"); + close(fd); + return -1; + } + continue; + } + break; + } + udpPid = fork(); + if (udpPid == -1) { + perror("Forking udp listener failed"); + close(fd); + return -1; + } + if (udpPid != 0) { + close(fd); + return port; + } + // Child + prctl(PR_SET_PDEATHSIG, SIGTERM); + for (;;) { + struct sockaddr_in remote; + socklen_t remoteLen = sizeof(remote); + uint8_t buffer[KEYLEN]; + ssize_t ret = recvfrom(fd, buffer, KEYLEN, 0, (struct sockaddr*)&remote, &remoteLen); + if (ret == KEYLEN && memcmp(key1, buffer, KEYLEN) == 0) { + if (sendto(fd, passwordEnc, passwordLen, 0, (struct sockaddr*)&remote, sizeof(remote)) == -1) { + perror("Could not send password to remote peer"); + } + } + } +} + diff --git a/core/modules/run-virt/winres/compile b/core/modules/run-virt/winres/compile new file mode 100755 index 00000000..da2f59eb --- /dev/null +++ b/core/modules/run-virt/winres/compile @@ -0,0 +1,13 @@ +#!/bin/sh + +rm -- winres.exe +i686-w64-mingw32-windres -i winres.rc -o resource.res -O coff +i686-w64-mingw32-gcc -Wall -Wextra -pedantic -Wno-unused-parameter -flto -std=c99 -Os -Wl,--subsystem,windows -o winres.exe winres.c resource.res -lole32 -luuid -lgdi32 -lws2_32 -lshell32 -lmpr -lshlwapi +rm -- resource.res +if strip winres.exe; then + echo "Successfully created winres.exe" + echo "It has NOT been moved to data/.../openslx.exe" +else + echo "FAIL FAIL FAIL no EXE generated!" +fi + diff --git a/core/modules/run-virt/winres/winres.c b/core/modules/run-virt/winres/winres.c new file mode 100644 index 00000000..44654161 --- /dev/null +++ b/core/modules/run-virt/winres/winres.c @@ -0,0 +1,1166 @@ +#define NTDDI_VERSION NTDDI_VISTA +#define WINVER 0x0602 +#define _WIN32_WINNT 0x0602 +#define WIN32_LEAN_AND_MEAN +#define _UNICODE +#define UNICODE +#define NO_SHLWAPI_STRFCNS +#include <windows.h> +#include <winsock2.h> +#include <winnetwk.h> +#include <mmdeviceapi.h> +#include <endpointvolume.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <initguid.h> +#include <stdint.h> +#include <stdarg.h> +#include <wchar.h> +#include <time.h> +#include <shlobj.h> +#include <shlguid.h> +#include <strsafe.h> +#include <tlhelp32.h> +#include <shlwapi.h> +#include <shellapi.h> + +DEFINE_GUID(ID_IAudioEndpointVolume, 0x5CDF2C82, 0x841E, 0x4546, 0x97, 0x22, 0x0C, 0xF7, 0x40, 0x78, 0x22, 0x9A); +DEFINE_GUID(ID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6); +DEFINE_GUID(ID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E); + +#define WM_SOCKDATA (WM_APP+1) + +typedef struct { + const char* path; + const char* pathIp; + const char* letter; + const char* shortcut; + const char* user; + const char* pass; + BOOL success; +} netdrive_t; + +static const ssize_t KEYLEN = 16; +#define DRIVEMAX (100) +#define LOGFILELEN (300) +#define SETTINGS_FILE "B:\\OPENSLX.INI" +#define SETTINGS_FILE_W L"B:\\OPENSLX.INI" + +static BOOL _debug = FALSE; + +static HINSTANCE hKernel32, hShell32; +static OSVERSIONINFO winVer; +static BOOL bGetShares = FALSE; +static netdrive_t drives[DRIVEMAX]; +static wchar_t desktopPath[MAX_PATH+1], tempPath[MAX_PATH+1], programsPath[MAX_PATH+1], windowsPath[MAX_PATH+1]; +static wchar_t logFile[LOGFILELEN]; +static DWORD _startTime; +#define FS_UNKNOWN (-1) +#define FS_ERROR (0) +#define FS_OK (1) +static int _folderStatus = FS_UNKNOWN; // -1 = Not handled yet, 0 = patching failed, 1 = remapped ok +#define RM_NONE (0) +#define RM_NATIVE (1) +#define RM_NATIVE_FALLBACK (2) +#define RM_VMWARE (3) +static int _remapMode = RM_NONE; +static const char* _remapHomeDrive = NULL; + +#define SCRIPTFILELEN (50) +char _scriptFile[SCRIPTFILELEN]; + +struct { + BOOL documents; + BOOL downloads; + BOOL desktop; + BOOL media; + BOOL other; +} remap; +static BOOL _createMissingRemap = FALSE; + +static void setPowerState(); +static int setResolution(); +static int muteSound(); +static int setShutdownText(); +static void readShareFile(); +static BOOL mountNetworkShares(); +static int queryPasswordDaemon(); +static BOOL fileExists(wchar_t* szPath); +static BOOL folderExists(wchar_t* szPath); +static void patchUserPaths(wchar_t *letter); +static void remapViaSharedFolder(); + +static HRESULT createFolderShortcut(wchar_t* sTargetfile, wchar_t* sLinkfile, wchar_t* comment); + +static void alog(const char *fmt, ...) +{ + FILE *f = _wfopen(logFile, L"a+"); + if (f == NULL) return; + time_t raw = time(NULL); + struct tm *tinf; + char buffer[80]; + tinf = localtime(&raw); + strftime(buffer, 80, "%I:%M:%S ", tinf); + fputs(buffer, f); + va_list args; + va_start(args, fmt); + vfprintf(f, fmt, args); + va_end(args); + fputc('\n', f); + fclose(f); +} + +static void wlog(const wchar_t *fmt, ...) +{ + wchar_t wbuffer[1000]; + char abuffer[1000]; + va_list args; + + FILE *f = _wfopen(logFile, L"a+"); + if (f == NULL) return; + time_t raw = time(NULL); + struct tm *tinf; + tinf = localtime(&raw); + strftime(abuffer, 1000, "%I:%M:%S ", tinf); + fputs(abuffer, f); + + va_start(args, fmt); + StringCchVPrintfW(wbuffer, 1000, fmt, args); + va_end(args); + if (WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, abuffer, 1000, NULL, NULL) == 0) { + snprintf(abuffer, 1000, "Cannot wlog: widechar to utf8 failed."); + } + fputs(abuffer, f); + fputc('\n', f); + fclose(f); +} + +static void CALLBACK resetShutdown(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + static BOOL bInProc = FALSE; + if (!bInProc) { + bInProc = TRUE; + setShutdownText(); + bInProc = FALSE; + } +} + +static void CALLBACK tmrResolution(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + static BOOL bInProc = FALSE; + if (!bInProc) { + bInProc = TRUE; + if (setResolution() == 0) { + KillTimer(hWnd, idEvent); + } + bInProc = FALSE; + } +} + +static void CALLBACK setupNetworkDrives(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + static BOOL bInProc = FALSE; + static int fails = 0; + if (bInProc) + return; + bInProc = TRUE; + if (!bGetShares && (_remapMode == RM_NATIVE_FALLBACK || _remapMode == RM_VMWARE)) { + remapViaSharedFolder(); + } else { + int ret = queryPasswordDaemon(); + if (ret != 0) { + if (++fails < 10) + goto exit_func; + alog("queryPasswordDaemon returned %d", ret); + } else { + if (!mountNetworkShares()) { + if (GetTickCount() - _startTime < 30000 && ++fails < 15) + goto exit_func; + } + } + // Finished successfully or failed completely + if (_folderStatus != FS_OK && (_remapMode == RM_NATIVE_FALLBACK || _remapMode == RM_VMWARE)) { + remapViaSharedFolder(); + } + } + KillTimer(hWnd, idEvent); + if (_remapMode != RM_NONE) { + if (_folderStatus == FS_ERROR) { + MessageBoxA(NULL, "Fehler beim Einbinden des Home-Verzeichnisses. Bitte nichts Wichtiges in der VM speichern, sondern z.B. einen USB-Stick verwenden.", "Warnung", MB_ICONERROR); + } else if (_folderStatus == FS_UNKNOWN) { + MessageBoxA(NULL, "Kein Home-Verzeichnis gefunden. Bitte nichts Wichtiges in der VM speichern, sondern z.B. einen USB-Stick verwenden.", "Warnung", MB_ICONERROR); + } + } + return; +exit_func: + bInProc = FALSE; +} + +typedef HRESULT (*GFPTYPE)(HWND, int, HANDLE, DWORD, wchar_t*); +typedef HRESULT (*GSFTYPE)(HWND, int, ITEMIDLIST**); +typedef BOOL (*ID2PTYPE)(const ITEMIDLIST*, wchar_t*); + +/** + * Load given path (CSIDL). Store in default (must be allocated to hold at least MAX_PATH+1 chars). + * If it could not be retrieved by CSIDL and envName is not NULL, it will be read from the + * environment if possible. + * fallback will be used if everything else fails. + * fallback can be NULL, in which case the fallback is empty. + */ +static void loadPath(wchar_t *dest, int csidl, wchar_t *envName, wchar_t *fallback) +{ + if (hShell32 != NULL) { + GFPTYPE aGetFolderPath = (GFPTYPE)GetProcAddress(hShell32, "SHGetFolderPathW"); + if (aGetFolderPath != NULL) { + if ((aGetFolderPath)(HWND_DESKTOP, csidl, NULL, SHGFP_TYPE_CURRENT, dest) == S_OK) + return; + } + // Fallback + GSFTYPE aGetSpecialFolder = (GSFTYPE)GetProcAddress(hShell32, "SHGetSpecialFolderLocation"); + ID2PTYPE aPathToId = (ID2PTYPE)GetProcAddress(hShell32, "SHGetPathFromIDListW"); + if (aGetSpecialFolder != NULL && aPathToId != NULL) { + ITEMIDLIST *list = NULL; + HRESULT ret1 = (aGetSpecialFolder)(HWND_DESKTOP, csidl, &list); + BOOL ret2 = FALSE; + if (ret1 == 0) { + ret2 = (aPathToId)(list, dest); + } + if (list != NULL) { + CoTaskMemFree(list); + } + if (ret2) + return; + } + } + if (envName != NULL) { + // Fallback + DWORD ret = GetEnvironmentVariableW(envName, dest, MAX_PATH+1); + if (ret > 0 && ret <= MAX_PATH) + return; + } + if (fallback != NULL) { + StringCchPrintfW(programsPath, MAX_PATH+1, fallback); + return; + } + *dest = '\0'; +} + +static void loadPaths() +{ + // Determine a couple of default directories + // dest, id, env, fallback + loadPath(programsPath, CSIDL_PROGRAM_FILES, L"ProgramFiles", L"C:\\Program Files"); + loadPath(windowsPath, CSIDL_WINDOWS, L"windir", L"C:\\WINDOWS"); + loadPath(desktopPath, CSIDL_DESKTOPDIRECTORY, NULL, NULL); + if (GetTempPathW(MAX_PATH+1, tempPath) == 0) { + DWORD ret = GetEnvironmentVariableW(L"TEMP", tempPath, MAX_PATH+1); + if (ret == 0 || ret > MAX_PATH) { + tempPath[0] = 0; + } + } + //wlog(L"Programs: %s, Windows: %s, Desktop: %s, Temp: %s", programsPath, windowsPath, desktopPath, tempPath); + StringCchPrintfW(logFile, LOGFILELEN, L"%s\\%s", desktopPath, L"openslx.log"); + FILE *tfh = _wfopen(logFile, L"a+"); + if (tfh == NULL) { + StringCchPrintfW(logFile, LOGFILELEN, L"%s\\%s", tempPath, L"openslx.log"); + tfh = _wfopen(logFile, L"a+"); + } + if (tfh != NULL) { + fseek(tfh, 0, SEEK_END); + long pos = ftell(tfh); + fclose(tfh); + if (pos < 3) { + _wremove(logFile); + } + } + // Read settings from ini file + remap.documents = GetPrivateProfileIntA("remap", "documents", 1, SETTINGS_FILE) != 0; + remap.downloads = GetPrivateProfileIntA("remap", "downloads", 1, SETTINGS_FILE) != 0; + remap.desktop = GetPrivateProfileIntA("remap", "desktop", 0, SETTINGS_FILE) != 0; + remap.media = GetPrivateProfileIntA("remap", "media", 1, SETTINGS_FILE) != 0; + remap.other = GetPrivateProfileIntA("remap", "other", 0, SETTINGS_FILE) != 0; + _createMissingRemap = GetPrivateProfileIntA("openslx", "createMissingRemap", 1, SETTINGS_FILE) != 0; + _remapMode = GetPrivateProfileIntA("openslx", "remapMode", RM_NATIVE_FALLBACK, SETTINGS_FILE); + if (_remapMode == RM_NONE) { + _folderStatus = FS_OK; + } + char buffer[10]; + GetPrivateProfileStringA("openslx", "homeDrive", "H:", buffer, sizeof(buffer), SETTINGS_FILE); + buffer[0] = toupper(buffer[0]); + buffer[1] = ':'; + buffer[2] = '\0'; + _remapHomeDrive = strdup(buffer); + // Get extension for autorun script + GetPrivateProfileStringA("openslx", "scriptExt", "", buffer, sizeof(buffer), SETTINGS_FILE); + StringCchPrintfA(_scriptFile, SCRIPTFILELEN, "B:\\runscript%s", buffer); +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + hKernel32 = LoadLibraryW(L"kernel32.dll"); + if (hKernel32 == NULL) { + alog("Cannot load kernel32.dll"); + } + hShell32 = LoadLibraryW(L"shell32.dll"); + if (hShell32 == NULL) { + alog("Cannot load shell32.dll"); + } + winVer.dwOSVersionInfoSize = sizeof(winVer); + BOOL retVer = GetVersionEx(&winVer); + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + _startTime = GetTickCount(); + loadPaths(); + if (lpCmdLine != NULL && strstr(lpCmdLine, "debug") != NULL) { + _debug = TRUE; + alog("Windows Version %d.%d", (int)winVer.dwMajorVersion, (int)winVer.dwMinorVersion); + } + // Mute sound by default + if (retVer && winVer.dwMajorVersion >= 6) + muteSound(); + // Disable screen saver as it might give the false impression that the session is securely locked + SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0); + // Same with standby + setPowerState(); + // Any network shares to mount? + readShareFile(); + if (bGetShares || _remapMode != RM_NONE) { + UINT_PTR tRet = SetTimer(NULL, 0, 1550, (TIMERPROC)&setupNetworkDrives); + if (tRet == 0) { + alog("Could not create timer for mounting network shares: %d", (int)GetLastError()); + } + } + // Shutdown button label + if (retVer && winVer.dwMajorVersion == 6 && winVer.dwMinorVersion == 1) { + // Only on Windows 7 + // Repeatedly set caption + UINT_PTR tRet = SetTimer(NULL, 0, 5230, (TIMERPROC)&resetShutdown); + if (tRet == 0) { + alog("Could not create timer for shutdown button: %d", (int)GetLastError()); + } + } + // Resolution + if (fileExists(SETTINGS_FILE_W) && setResolution() != 0) { + UINT_PTR tRet = SetTimer(NULL, 0, 3111, (TIMERPROC)&tmrResolution); + if (tRet == 0) { + alog("Could not create timer for resolution setting: %d", (int)GetLastError()); + } + } + // Runscript (if any) + if (PathFileExistsA(_scriptFile)) { + ShellExecuteA(NULL, "open", _scriptFile, NULL, "B:\\", SW_SHOWNORMAL); + } + // Message pump + MSG Msg; + while(GetMessage(&Msg, NULL, 0, 0) > 0) { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + FreeLibrary(hKernel32); + FreeLibrary(hShell32); + return 0; +} + +static BOOL fileExists(wchar_t* szPath) +{ + DWORD dwAttrib = GetFileAttributesW(szPath); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) == 0); +} + +static BOOL folderExists(wchar_t* szPath) +{ + DWORD dwAttrib = GetFileAttributesW(szPath); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0); +} + +static int execute(wchar_t *path, wchar_t *arguments) +{ + STARTUPINFOW si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + ZeroMemory(&pi, sizeof(pi)); + si.cb = sizeof(si); + if (!CreateProcessW(path, arguments, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { + return -1; + } + while (MsgWaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE, QS_SENDMESSAGE) == WAIT_OBJECT_0+1) { + MSG Msg; + while(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE)) { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } + DWORD exitCode; + BOOL ret = GetExitCodeProcess(pi.hProcess, &exitCode); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + if (!ret) { + return -2; + } + return (int)exitCode; +} + +typedef EXECUTION_STATE (WINAPI *TETYPE)(EXECUTION_STATE); + +static void setPowerState() +{ + // Disable standby and idle-mode (this is a VM!) + if (hKernel32 == NULL || winVer.dwMajorVersion < 5 || (winVer.dwMajorVersion == 5 && winVer.dwMinorVersion < 1)) + return; + TETYPE aExecState = (TETYPE)GetProcAddress(hKernel32, "SetThreadExecutionState"); + if (aExecState == NULL) { + alog("Cannot get SetThreadExecutionState from kernel32.dll"); + return; + } + if (winVer.dwMajorVersion >= 6) { // Vista+ + (aExecState)(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED | ES_AWAYMODE_REQUIRED); + } else { // XP/2003 + (aExecState)(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); + } +} + +static int setResolution() +{ + int ret; + static int width = 0, height = 0; + if (width == 0 && height == 0) { + // use config file in floppy + char data[200] = ""; + GetPrivateProfileStringA("openslx", "resolution", "", data, sizeof(data), SETTINGS_FILE); + char *x = strchr(data, 'x'); + if (x == NULL) { + alog("Malformed resolution in " SETTINGS_FILE ": '%s'", data); + return 0; + } + *x++ = '\0'; + width = atoi(data); + height = atoi(x); + if (width < 320 || height < 240) { + alog("Invalid resolution in " SETTINGS_FILE ": '%s' (parsed width=%d, height=%d)", data, width, height); + return 0; + } + } + // Try vmware tools + static wchar_t path[MAX_PATH] = L""; + if (path[0] == 0) { + StringCchPrintfW(path, MAX_PATH, L"%s\\VMware\\VMware Tools\\VMwareResolutionSet.exe", programsPath); + if (!fileExists(path)) { + // Strip (x86) if found and try again + wchar_t *x86 = wcsstr(path, L" (x86)"); + if (x86 != NULL) { + while ((*x86 = *(x86 + 6)) != 0) ++x86; + } + } + if (!fileExists(path)) { + char buffer[300]; + WideCharToMultiByte(CP_UTF8, 0, path, -1, buffer, 300, NULL, NULL); + alog("vmware tools not found, using winapi to set resolution (path: %s)", buffer); + } + } + if (path[0] != 0 && fileExists(path)) { + wchar_t cmdline[MAX_PATH]; + StringCchPrintfW(cmdline, MAX_PATH, L"VMwareResolutionSet.exe 0 1 , 0 0 %d %d", width, height); + int ret = execute(path, cmdline); + if (ret == -1) { + alog("VmwareRes: CreateProcess failed (%d)", (int)GetLastError()); + } else if (ret == -2) { + alog("VmwareRes: GetExitCode failed (%d)", (int)GetLastError()); + } + } + // Use WinAPI as fallback + DEVMODE mode; + int query = 1337; + memset(&mode, 0, sizeof(mode)); + mode.dmSize = sizeof(mode); + // MSDN recommends to fill the struct first by querying.... + query = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode); + // Then set our own desired mode + mode.dmPelsWidth = width; + mode.dmPelsHeight = height; + mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; + ret = ChangeDisplaySettings(&mode, CDS_GLOBAL | CDS_UPDATEREGISTRY); + if (ret != DISP_CHANGE_SUCCESSFUL) { + ret = ChangeDisplaySettings(&mode, CDS_GLOBAL); + } + if (ret != DISP_CHANGE_SUCCESSFUL) { + ret = ChangeDisplaySettings(&mode, CDS_UPDATEREGISTRY); + } + if (ret != DISP_CHANGE_SUCCESSFUL) { + ret = ChangeDisplaySettings(&mode, 0); + } + if (ret != DISP_CHANGE_SUCCESSFUL) { + static int fails = 0; + if (++fails == 5) { + alog("Fehler beim Setzen der Auflösung: %d (soll: 0) / %d ( soll: !0) - Zielaufloesung: %d * %d", + ret, query, width, height); + } + return 1; + } + return 0; +} + +static int muteSound() +{ + IMMDeviceEnumerator *deviceEnumerator = NULL; + HRESULT hr = CoCreateInstance(&ID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &ID_IMMDeviceEnumerator, (LPVOID *)&deviceEnumerator); + if (hr != S_OK) { + alog("CoCreateInstance failed. Cannot mute."); + return 1; + } + //deviceEnumerator->lpVtbl->AddRef(deviceEnumerator); + IMMDevice *defaultDevice = NULL; + hr = deviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(deviceEnumerator, eRender, eConsole, &defaultDevice); + if (hr != S_OK) { + alog("GetDefaultAudioEndpoint failed. Cannot mute."); + return 2; + } + //defaultDevice->lpVtbl->AddRef(defaultDevice); + //deviceEnumerator->lpVtbl->Release(deviceEnumerator); + IAudioEndpointVolume *endpointVolume = NULL; + hr = defaultDevice->lpVtbl->Activate(defaultDevice, &ID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume); + if (hr != S_OK) { + alog("IMMDevice::Activate() failed. Cannot mute."); + return 3; + } + //endpointVolume->lpVtbl->AddRef(endpointVolume); + //defaultDevice->lpVtbl->Release(defaultDevice); + float targetVolume = 1; + endpointVolume->lpVtbl->SetMasterVolumeLevelScalar(endpointVolume, targetVolume, NULL); + endpointVolume->lpVtbl->SetMute(endpointVolume, TRUE, NULL); + //endpointVolume->lpVtbl->Release(endpointVolume); + //CoUninitialize(); + return 0; +} + +static int setShutdownText() +{ + HWND hMenu = FindWindowA("DV2ControlHost", NULL); + if (hMenu == NULL) return 1; // TODO: Enum all of them + HWND hPane = FindWindowExA(hMenu, NULL, "DesktopLogoffPane", NULL); + if (hMenu == NULL) return 2; + HWND hButton = FindWindowExA(hPane, NULL, "Button", NULL); + if (hButton == NULL) return 3; + if (SendMessageA(hButton, WM_SETTEXT, 0, (LPARAM)"Abmelden") != TRUE) return 4; + return 0; +} + +static char *shost = NULL, *sport = NULL, *suser = NULL, *spass = NULL; +static uint8_t *bkey1 = NULL, *bkey2 = NULL; + +static char* xorString(const uint8_t* text, int len, const uint8_t* key); +static int getbin(int x); +static uint8_t* hex2bin(char *szHexString); + +static char* getToken(char **ptr, BOOL doDup) +{ + if (*ptr == NULL || **ptr == '\0') return NULL; + char *dest = *ptr; + while (**ptr != '\0') { + if (**ptr == '\n' || **ptr == '\r' || **ptr == '\t') { + *(*ptr)++ = '\0'; + break; + } + (*ptr)++; + } + if (doDup) { + dest = strdup(dest); + } + return dest; +} + +const char* uncReplaceFqdnByIp(const char* path) +{ + if (path == NULL || path[0] != '\\' || path[1] != '\\') + return NULL; + const char *host = path + 2; + const char *rest = strchr(host, '\\'); + if (rest == NULL || rest - host >= 200) + return NULL; + char name[201]; + strncpy(name, host, rest - host); + name[rest-host] = '\0'; + if (_debug) { + alog("Trying to resolve '%s'...", name); + } + struct hostent *remote = gethostbyname(name); + if (remote == NULL || remote->h_addrtype != AF_INET || remote->h_addr_list[0] == 0) + return NULL; + struct in_addr addr; + addr.s_addr = *(u_long*)remote->h_addr_list[0]; + char *ip = inet_ntoa(addr); + if (ip == NULL) + return NULL; + size_t len = 2 /* \\ */ + strlen(ip) /* 1.2.3.4 */ + strlen(rest) /* \path\to\share */ + 1 /* nullchar */; + char *retval = malloc(len); + snprintf(retval, len, "\\\\%s%s", ip, rest); + if (_debug) { + alog("Turned '%s' into '%s'", path, retval); + } + return retval; +} + +#define FREENULL(x) do { free((void*)(x)); (x) = NULL; } while (0) + +static void readShareFile() +{ + if (bGetShares) + return; + memset(drives, 0, sizeof(drives)); + FILE *h = fopen("B:\\shares.dat", "r"); + if (h == NULL) return; + char creds[300] = "", buffer[500] = ""; + char *skey1 = NULL, *skey2 = NULL; + if (fgets(creds, sizeof(creds), h) != NULL) { + char *ptr = creds; + shost = getToken(&ptr, TRUE); + sport = getToken(&ptr, TRUE); + skey1 = getToken(&ptr, FALSE); + skey2 = getToken(&ptr, FALSE); + suser = getToken(&ptr, TRUE); + } + int idx = 0; + while (fgets(buffer, sizeof(buffer), h) != NULL && idx < DRIVEMAX) { + char *ptr = buffer; + netdrive_t *d = &drives[idx]; + d->path = getToken(&ptr, TRUE); + d->letter = getToken(&ptr, TRUE); + d->shortcut = getToken(&ptr, TRUE); + d->user = getToken(&ptr, TRUE); + d->pass = getToken(&ptr, TRUE); + if (d->path == NULL || d->path[0] == '\0') + goto drive_fail; + d->success = FALSE; + // Hack: For unknown reasons, with some servers mounting fails using a fqdn, but using the ip address instead succeeds. + d->pathIp = uncReplaceFqdnByIp(d->path); + // + idx++; + continue; +drive_fail: + FREENULL(d->path); + FREENULL(d->letter); + FREENULL(d->shortcut); + FREENULL(d->user); + FREENULL(d->pass); + } + fclose(h); + if (idx == 0) // No drives to map + return; + if (shost == NULL || sport == NULL || skey1 == NULL || skey2 == NULL || suser == NULL) // Credential stuff missing + return; + if (strlen(skey1) != KEYLEN*2 || strlen(skey2) != KEYLEN*2) // Messed up keys + return; + if (atoi(sport) < 1000 || atoi(sport) > 65535) // Invalid port + return; + bkey1 = hex2bin(skey1); + bkey2 = hex2bin(skey2); + if (bkey1 == NULL || bkey2 == NULL) + return; + bGetShares = TRUE; +} + +static void udpReceived(SOCKET sock); + +LRESULT CALLBACK slxWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg != WM_SOCKDATA) { + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + // Socket event + int event = LOWORD(lParam); + int errorCode = HIWORD(lParam); + if (errorCode == 0 && event == FD_READ) { + udpReceived((SOCKET)wParam); + } + return 0; +} + +static int queryPasswordDaemon() +{ + // See if preconditions are met + if (!bGetShares || spass != NULL) + return 0; + static int wsaInit = 1337; + static SOCKET sock = INVALID_SOCKET; + static HWND sockWnd = NULL; + // Init socket stuff + if (wsaInit == 1337) { + WSADATA wsa; + wsaInit = WSAStartup(MAKEWORD(2, 2), &wsa); + } + if (wsaInit != 0) + return 2; + // Create window for socket events + if (sockWnd == NULL) { + sockWnd = CreateWindowA("STATIC", "OpenSLX mystery window", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + if (sockWnd == NULL) + return GetLastError(); + SetWindowLong(sockWnd, GWL_WNDPROC, (LONG)&slxWindowProc); + } + // Create socket + if (sock == INVALID_SOCKET) { + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == INVALID_SOCKET) + return 3; + if (WSAAsyncSelect(sock, sockWnd, WM_SOCKDATA, FD_READ) != 0) { + alog("WSAAsyncSelect returned %d", (int)WSAGetLastError()); + } + } + SOCKADDR_IN remote; + remote.sin_family = AF_INET; + remote.sin_port = htons((u_short)atoi(sport)); + remote.sin_addr.s_addr = inet_addr(shost); + // Send out request for password + if (sendto(sock, (const char*)bkey1, KEYLEN, 0, (struct sockaddr*)&remote, sizeof(remote)) != KEYLEN) + return 4; + if (spass == NULL) + return -1; + return 0; +} + +static void udpReceived(SOCKET sock) +{ + int ret; + uint8_t buffer[200]; + ret = recv(sock, (char*)buffer, sizeof(buffer), 0); + // See if reply is valid + if (ret < 2) return; + uint16_t len = (uint16_t)(((uint16_t)buffer[0] << 8) | buffer[1]); + if (ret - 2 != len) return; + // Success + spass = xorString(buffer + 2, len, bkey2); + closesocket(sock); + mountNetworkShares(); +} + +#define BUFLEN (200) + +static DWORD mount(LPNETRESOURCEW share, LPWSTR pass, LPWSTR user) +{ + DWORD retval; + // Now try to mount + if ((pass && *pass) || (user && *user)) { + retval = WNetAddConnection2W(share, pass, user, CONNECT_TEMPORARY | CONNECT_CURRENT_MEDIA); + if (retval == NO_ERROR) { + return retval; + } + if (retval != ERROR_INVALID_PASSWORD && retval != ERROR_LOGON_FAILURE + && retval != ERROR_BAD_USERNAME && retval != ERROR_ACCESS_DENIED + && retval != ERROR_SESSION_CREDENTIAL_CONFLICT && retval != ERROR_BAD_NET_NAME) { + return retval; + } + } + static wchar_t nuser[BUFLEN] = L"\0", npass[BUFLEN] = L"\0"; + if (nuser[0] == 0 && npass[0] == 0) { + BOOL ok = TRUE; + if (suser != NULL) { + ok = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)suser, -1, (LPWSTR)nuser, BUFLEN) > 0 && ok; + } + if (spass != NULL) { + ok = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)spass, -1, (LPWSTR)npass, BUFLEN) > 0 && ok; + } + if (!ok) + return ERROR_INVALID_PARAMETER; + } + retval = WNetAddConnection2W(share, npass, nuser, CONNECT_TEMPORARY | CONNECT_CURRENT_MEDIA); + return retval; +} + +static void postSuccessfulMount(const netdrive_t *d, wchar_t *letter) +{ + if (d->shortcut != NULL && strlen(d->shortcut) != 0) { + wchar_t tmp[MAX_PATH], wShortcut[MAX_PATH], wTarget[MAX_PATH]; + MultiByteToWideChar(CP_UTF8, 0, d->shortcut, -1, tmp, MAX_PATH); + StringCchPrintfW(wShortcut, MAX_PATH, L"%s\\%s.lnk", desktopPath, tmp); + MultiByteToWideChar(CP_UTF8, 0, d->path, -1, tmp, MAX_PATH); + StringCchPrintfW(wTarget, MAX_PATH, L"\"%s\"", tmp); + DeleteFileW(wShortcut); + createFolderShortcut(wTarget, wShortcut, letter); + // Fix paths and kill explorer if it's the home directory + if (_folderStatus != FS_OK && strncmp(d->shortcut, "Home-", 5) == 0) { + BOOL isVmware = strcmp(d->path, "\\\\vmware-host\\Shared Folders\\home") == 0; + if (_remapMode == RM_NATIVE_FALLBACK + || (isVmware && _remapMode == RM_VMWARE) + || (!isVmware && _remapMode == RM_NATIVE)) { + patchUserPaths(letter); + } + } + } +} + +static BOOL mountNetworkShare(const netdrive_t *d, BOOL useIp) +{ + wchar_t path[BUFLEN] = L"", user[BUFLEN] = L"", pass[BUFLEN] = L"", letter[10] = L"", shortcut[BUFLEN] = L""; + int ok = -1; + if (useIp && d->pathIp[0] == '\0') + return FALSE; + const char *uncPath = useIp ? d->pathIp : d->path; + ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)uncPath, -1, (LPWSTR)path, BUFLEN) > 0; + if (d->letter != NULL) { + ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->letter, -1, (LPWSTR)letter, 10) > 0; + } + if (d->user != NULL) { + ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->user, -1, (LPWSTR)user, BUFLEN) > 0; + } + if (d->pass != NULL) { + ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->pass, -1, (LPWSTR)pass, BUFLEN) > 0; + } + if (d->shortcut != NULL) { + ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->shortcut, -1, (LPWSTR)shortcut, BUFLEN) > 0; + } + if (!ok || path[0] == 0) { // Convert failed/no path - return true anyways since retrying wouldn't change anything + alog("mountNetworkShare: utf8 to utf16 failed, or path empty (src: '%s')", uncPath); + return TRUE; + } + DWORD retval; + NETRESOURCEW share = { 0 }; + share.dwType = RESOURCETYPE_DISK; + share.lpLocalName = letter; + share.lpRemoteName = path; + share.lpProvider = NULL; + letter[1] = ':'; + letter[2] = 0; + letter[3] = 0; + if (letter[0] != 0) { + // Try with specific letter + // Connect defined share + retval = mount(&share, pass, user); + if (retval == NO_ERROR) { + postSuccessfulMount(d, letter); + return TRUE; + } + if (retval != ERROR_ALREADY_ASSIGNED && retval != ERROR_DEVICE_ALREADY_REMEMBERED + && retval != ERROR_CONNECTION_UNAVAIL) { + alog("mountNetworkShare: with letter failed: %d", (int)retval); + return FALSE; + } + } + // Try to find free drive letter + for (letter[0] = 'Z'; letter[0] > 'C'; --letter[0]) { + retval = mount(&share, pass, user); + if (retval == ERROR_ALREADY_ASSIGNED || retval == ERROR_DEVICE_ALREADY_REMEMBERED + || retval == ERROR_CONNECTION_UNAVAIL) + continue; + if (retval == NO_ERROR) { + postSuccessfulMount(d, letter); + return TRUE; + } + alog("mountNetworkShare: without letter failed: %d", (int)retval); + if (retval == ERROR_INVALID_PASSWORD || retval == ERROR_LOGON_FAILURE + || retval == ERROR_BAD_USERNAME || retval == ERROR_ACCESS_DENIED + || retval == ERROR_SESSION_CREDENTIAL_CONFLICT) { + return TRUE; + } + return FALSE; + } + return FALSE; +} + +static BOOL mountNetworkShares() +{ + if (!bGetShares) + return TRUE; + if (spass == NULL) + return FALSE; + int failCount = 0; + for (int i = 0; i < DRIVEMAX; ++i) { + if (drives[i].path == NULL) + break; + if (drives[i].success) + continue; + if (mountNetworkShare(&drives[i], FALSE)) { + drives[i].success = TRUE; + } else if (mountNetworkShare(&drives[i], TRUE)) { + drives[i].success = TRUE; + } else { + failCount++; + } + } + if (failCount > 0) + return FALSE; + SecureZeroMemory(spass, strlen(spass)); + return TRUE; +} + +static void remapViaSharedFolder() +{ + static const char* homeDirA = "\\\\vmware-host\\Shared Folders\\home"; // thiscase! + static const wchar_t* homeDirW = L"\\\\vmware-host\\shared folders\\home"; // lowercase! + static BOOL once = FALSE; + if (once) return; + once = TRUE; + netdrive_t d; + d.path = homeDirA; + d.letter = _remapHomeDrive; + d.shortcut = "Home-Verzeichnis"; + d.user = ""; + d.pass = ""; + d.success = FALSE; + // See if it's already mapped + wchar_t letter[5] = L"C:\\"; + char buffer[600]; + UNIVERSAL_NAME_INFOW *uni = (UNIVERSAL_NAME_INFOW*)buffer; + for (letter[0] = 'D'; letter[0] <= 'Z'; ++letter[0]) { + //wlog(L"Checking %s", letter); + DWORD len = (DWORD)sizeof(buffer); + if (NO_ERROR == WNetGetUniversalNameW(letter, UNIVERSAL_NAME_INFO_LEVEL, uni, &len)) { + _wcslwr(uni->lpUniversalName); + //wlog(L"Is %s", uni->lpUniversalName); + if (wcscmp(uni->lpUniversalName, homeDirW) == 0) { + letter[2] = '\0'; + postSuccessfulMount(&d, letter); + return; + } + } + } + // Map vmware shared folder + mountNetworkShare(&d, FALSE); +} + +static char* xorString(const uint8_t* text, int len, const uint8_t* key) +{ + int i; + uint8_t *retval = malloc(len + 1); + uint8_t *ptr = retval; + for (i = 0; i < len; ++i) { + ptr[i] = text[i] ^ key[i % KEYLEN]; + } + ptr[len] = '\0'; + return (char*)retval; +} + +static int getbin(int x) +{ + if (x >= '0' && x <= '9') + return x - '0'; + if (x >= 'A' && x <= 'F') + return x - 'A' + 10; + return x - 'a' + 10; +} + +static uint8_t* hex2bin(char *szHexString) +{ + int size = strlen(szHexString) / 2, i; + char *p = szHexString; + uint8_t *pBinary = malloc(size); + + for(i = 0; i < size; i++, p += 2) { + pBinary[i] = (uint8_t)((getbin(p[0]) << 4) | getbin(p[1])); + } + return pBinary; +} + +// Stuff for creating a simple shortcut (.lnk) + +static HRESULT createFolderShortcut(wchar_t* targetDir, wchar_t* linkFile, wchar_t* comment) +{ + HRESULT hRes; /* Returned COM result code */ + IShellLink* pShellLink; /* IShellLink object pointer */ + IPersistFile* pPersistFile; /* IPersistFile object pointer */ + + hRes = E_INVALIDARG; + if ( + (targetDir != NULL) && (wcslen(targetDir) > 0) && + (linkFile != NULL) && (wcslen(linkFile) > 0) + ) { + hRes = CoCreateInstance( + &CLSID_ShellLink, /* pre-defined CLSID of the IShellLink object */ + NULL, /* pointer to parent interface if part of aggregate */ + CLSCTX_INPROC_SERVER, /* caller and called code are in same process */ + &IID_IShellLink, /* pre-defined interface of the IShellLink object */ + (void**)&pShellLink); /* Returns a pointer to the IShellLink object */ + if (SUCCEEDED(hRes)) { + wchar_t explorer[MAX_PATH]; + StringCchPrintfW(explorer, MAX_PATH, L"\"%s\\explorer.exe\"", windowsPath); + // Set the fields in the IShellLink object + hRes = pShellLink->lpVtbl->SetPath(pShellLink, explorer); + hRes = pShellLink->lpVtbl->SetArguments(pShellLink, targetDir); + if (comment != NULL) { + hRes = pShellLink->lpVtbl->SetDescription(pShellLink, comment); + } + StringCchPrintfW(explorer, MAX_PATH, L"%s\\system32\\imageres.dll", windowsPath); + hRes = pShellLink->lpVtbl->SetIconLocation(pShellLink, explorer, 137); + + /* Use the IPersistFile object to save the shell link */ + hRes = pShellLink->lpVtbl->QueryInterface( + pShellLink, /* existing IShellLink object */ + &IID_IPersistFile, /* pre-defined interface of the IPersistFile object */ + (void**)&pPersistFile); /* returns a pointer to the IPersistFile object */ + if (SUCCEEDED(hRes)) { + hRes = pPersistFile->lpVtbl->Save(pPersistFile, linkFile, TRUE); + pPersistFile->lpVtbl->Release(pPersistFile); + } + pShellLink->lpVtbl->Release(pShellLink); + } + + } + return (hRes); +} + +// Patch user directories + +static BOOL patchRegPath(BOOL *patchOk, BOOL *anyMapped, HKEY hKey, wchar_t *letter, wchar_t *value, ...) +{ + wchar_t *folder = NULL; + wchar_t first[MAX_PATH] = {0}; + wchar_t path[MAX_PATH]; + wchar_t oldvalue[MAX_PATH]; + va_list args; + LONG ret; + DWORD type; + DWORD len; + // Let's check the path in the registry first + len = (DWORD)(sizeof(oldvalue) - sizeof(wchar_t)); + ret = RegQueryValueExW(hKey, value, NULL, &type, (BYTE*)oldvalue, &len); + if (ret == ERROR_SUCCESS && (type == REG_EXPAND_SZ || type == REG_SZ)) { + len /= 2; + oldvalue[len] = '\0'; + if (towlower(oldvalue[0]) == towlower(letter[0]) && folderExists(oldvalue)) // Same drive, folder exists, yay + return TRUE; + } + // Old registry value doesn't fit - figure out new value + va_start(args, value); + while ((folder = va_arg(args, wchar_t*)) != NULL) { + StringCchPrintfW(path, MAX_PATH, L"%s\\%s", letter, folder); + if (folderExists(path)) + break; + if (*first == 0) { + wcsncpy(first, path, MAX_PATH); + } + } + va_end(args); + if (folder != NULL) { + // Found something existing + folder = path; + } else if (!_createMissingRemap) { + // Nothing found, must not create + wlog(L"Cannot remap %s to %s: target not found!", value, first); + return FALSE; + } else { + // Nothing found, use first element of list and create it + folder = first; + CreateDirectoryW(folder, NULL); + } + _wcslwr(folder); + _wcslwr(oldvalue); + if (wcscmp(folder, oldvalue) == 0) { + // Path already in registry, don't update + return TRUE; + } + ret = RegSetValueExW(hKey, value, 0, REG_SZ, (BYTE*)folder, (wcslen(folder) + 1) * sizeof(wchar_t)); + if (ret == ERROR_SUCCESS) { + *anyMapped = TRUE; + return TRUE; + } + wlog(L"Setting reg key %s to %s failed (return value %ld)", value, folder, (long)ret); + *patchOk = FALSE; + return FALSE; +} + +typedef HANDLE (WINAPI *SNTYPE)(DWORD, DWORD); +typedef BOOL (WINAPI *P32TYPE)(HANDLE, PROCESSENTRY32W*); + +static void patchUserPaths(wchar_t *letter) +{ + LONG ret; + HKEY hKey; + BOOL patchOk = TRUE; + BOOL killOk = FALSE; + BOOL anyMapped = FALSE; + _folderStatus = FS_ERROR; + ret = RegOpenKeyExW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", + 0, KEY_WOW64_64KEY | KEY_READ | KEY_WRITE, &hKey); + if (ret != ERROR_SUCCESS) { + alog("Opening registry for patching of pathes failed with return code %ld", (long)ret); + return; + } + // Ha! + const BOOL win10 = winVer.dwMajorVersion >= 10; + if (remap.other) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{56784854-C6CB-462B-8169-88E350ACB882}", L"Contacts", L"Profile\\Contacts", L"Kontakte", NULL); + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"Favorites", L"Favorites", L"Profile\\Favorites", L"Favoriten", NULL); + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{7D1D3A04-DEBB-4115-95CF-2F29DA2920DA}", L"Searches", L"Profile\\Searches", NULL); + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}", L"Links", L"Profile\\Links", NULL); + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}", L"Saved Games", L"SavedGames", L"Profile\\SavedGames", NULL); + } + if (remap.media) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"My Video", L"Videos", L"My Videos", L"Eigene Videos", NULL); + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"My Pictures", L"Pictures", L"My Pictures", L"Eigene Bilder", L"Bilder", NULL); + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"My Music", L"Music", L"My Music", L"Eigene Musik", L"Musik", NULL); + if (win10) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{35286a68-3c57-41a1-bbb1-0eae73d76c95}", L"Videos", L"My Videos", L"Eigene Videos", NULL); + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{0ddd015d-b06c-45d5-8c4c-f59713854639}", L"Pictures", L"My Pictures", L"Eigene Bilder", L"Bilder", NULL); + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{a0c69a99-21c8-4671-8703-7934162fcf1d}", L"Music", L"My Music", L"Eigene Musik", L"Musik", NULL); + } + } + if (remap.downloads) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{374DE290-123F-4565-9164-39C4925E467B}", L"Downloads", L"Profile\\Downloads", NULL); + if (win10) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{7d83ee9b-2244-4e70-b1f5-5393042af1e4}", L"Downloads", L"Profile\\Downloads", NULL); + } + } + if (remap.documents) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"Personal", L"Documents", L"Dokumente", L"My Documents", L"Eigene Dateien", NULL); + if (win10) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{f42ee2d3-909f-4907-8871-4c22fc0bf756}", L"Documents", L"Dokumente", L"My Documents", L"Eigene Dateien", NULL); + } + } + if (remap.desktop) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"Desktop", L"Windows Desktop", L"Desktop", L"Arbeitsfl\u00E4che", NULL); + if (win10) { + patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}", L"Windows Desktop", L"Desktop", L"Arbeitsfl\u00E4che", NULL); + } + } + RegCloseKey(hKey); + if (!anyMapped) { + _folderStatus = FS_OK; + return; + } + // Kill explorer + // Late binding + if (hKernel32 == NULL || winVer.dwMajorVersion < 5 || (winVer.dwMajorVersion == 5 && winVer.dwMinorVersion < 1)) { + return; + } + SNTYPE aCreateSnapshot; + P32TYPE aProcessFirst, aProcessNext; + aCreateSnapshot = (SNTYPE)GetProcAddress(hKernel32, "CreateToolhelp32Snapshot"); + if (aCreateSnapshot == NULL) { + alog("No CreateToolhelp32Snapshot in kernel.dll"); + return; + } + aProcessFirst = (P32TYPE)GetProcAddress(hKernel32, "Process32FirstW"); + if (aProcessFirst == NULL) { + alog("No Process32FirstW in kernel.dll"); + return; + } + aProcessNext = (P32TYPE)GetProcAddress(hKernel32, "Process32NextW"); + if (aProcessNext == NULL) { + alog("No Process32NextW in kernel.dll"); + return; + } + PROCESSENTRY32W entry; + entry.dwSize = sizeof(PROCESSENTRY32W); + HANDLE snapshot = (aCreateSnapshot)(TH32CS_SNAPPROCESS, 0); + if (snapshot != INVALID_HANDLE_VALUE && (aProcessFirst)(snapshot, &entry)) { + do { + if (_wcsicmp(entry.szExeFile, L"explorer.exe") == 0) { + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); + if (hProcess == NULL) { + alog("Cannot OpenProcess explorer.exe: Remapped paths will not work properly (GetLastError=%d)", (int)GetLastError()); + } else { + if (TerminateProcess(hProcess, 23)) { + killOk = TRUE; + } + CloseHandle(hProcess); + } + } + } while ((aProcessNext)(snapshot, &entry)); + } else { + alog("Could not get process list"); + } + CloseHandle(snapshot); + if (patchOk && killOk) { + _folderStatus = FS_OK; + } +} + diff --git a/core/modules/run-virt/winres/winres.manifest b/core/modules/run-virt/winres/winres.manifest new file mode 100644 index 00000000..a4ffc98e --- /dev/null +++ b/core/modules/run-virt/winres/winres.manifest @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> + <assemblyIdentity type="win32" + name="org.openslx.windows.winres" + version="4.0.0.0" + processorArchitecture="x86" + publicKeyToken="0000000000000000" + /> + <description>Sausageface</description> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel + level="asInvoker" + uiAccess="false" + /> + </requestedPrivileges> + </security> + </trustInfo> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!-- Windows 10 --> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> + <!-- Windows 8.1 --> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> + <!-- Windows Vista --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + <!-- Windows 7 --> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <!-- Windows 8 --> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + </application> + </compatibility> +</assembly> diff --git a/core/modules/run-virt/winres/winres.rc b/core/modules/run-virt/winres/winres.rc new file mode 100644 index 00000000..a9faf9a0 --- /dev/null +++ b/core/modules/run-virt/winres/winres.rc @@ -0,0 +1,4 @@ +#include <windows.h> + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "winres.manifest" + diff --git a/core/modules/safe-mode/data/etc/X11/Xsession.d/00-exam-mode b/core/modules/safe-mode/data/etc/X11/Xsession.d/00-exam-mode new file mode 100644 index 00000000..d4ab5359 --- /dev/null +++ b/core/modules/safe-mode/data/etc/X11/Xsession.d/00-exam-mode @@ -0,0 +1,9 @@ +#!/bin/ash Being sourced but hey + +. /opt/openslx/config + +if [ "x$SLX_EXAM" = "xyes" ]; then + # Force usage of vmchooser + set -- "$(which vmchooser)" +fi + diff --git a/core/modules/safe-mode/data/etc/systemd/system/basic.target.wants/safe-mode.service b/core/modules/safe-mode/data/etc/systemd/system/basic.target.wants/safe-mode.service new file mode 120000 index 00000000..c063e1a0 --- /dev/null +++ b/core/modules/safe-mode/data/etc/systemd/system/basic.target.wants/safe-mode.service @@ -0,0 +1 @@ +../safe-mode.service
\ No newline at end of file diff --git a/core/modules/safe-mode/data/etc/systemd/system/safe-mode.service b/core/modules/safe-mode/data/etc/systemd/system/safe-mode.service new file mode 100644 index 00000000..be0809b4 --- /dev/null +++ b/core/modules/safe-mode/data/etc/systemd/system/safe-mode.service @@ -0,0 +1,7 @@ +[Unit] +Description=Sets up safe mode (no magic keys, no tty switch, no openbox menu) +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/opt/openslx/scripts/systemd-safe_mode diff --git a/core/modules/screen-standby/data/etc/X11/Xreset.d/screen-standby b/core/modules/screen-standby/data/etc/X11/Xreset.d/screen-standby new file mode 120000 index 00000000..b25fe082 --- /dev/null +++ b/core/modules/screen-standby/data/etc/X11/Xreset.d/screen-standby @@ -0,0 +1 @@ +/opt/openslx/scripts/screen-standby
\ No newline at end of file diff --git a/core/modules/screen-standby/data/etc/X11/Xsession.d/screen-standby b/core/modules/screen-standby/data/etc/X11/Xsession.d/screen-standby new file mode 120000 index 00000000..b25fe082 --- /dev/null +++ b/core/modules/screen-standby/data/etc/X11/Xsession.d/screen-standby @@ -0,0 +1 @@ +/opt/openslx/scripts/screen-standby
\ No newline at end of file diff --git a/core/modules/screen-standby/data/etc/X11/Xsetup.d/screen-standby b/core/modules/screen-standby/data/etc/X11/Xsetup.d/screen-standby new file mode 120000 index 00000000..b25fe082 --- /dev/null +++ b/core/modules/screen-standby/data/etc/X11/Xsetup.d/screen-standby @@ -0,0 +1 @@ +/opt/openslx/scripts/screen-standby
\ No newline at end of file diff --git a/core/modules/screen-standby/data/opt/openslx/scripts/screen-standby b/core/modules/screen-standby/data/opt/openslx/scripts/screen-standby new file mode 100755 index 00000000..74a09556 --- /dev/null +++ b/core/modules/screen-standby/data/opt/openslx/scripts/screen-standby @@ -0,0 +1,29 @@ +#!/bin/ash + +# This is usually sourced by Xstartup/session/reset + +do_standby_stuff () { + . /opt/openslx/config + # Make sure SLX_SCREEN_STANDBY_TIMEOUT is numeric + TO=${SLX_SCREEN_STANDBY_TIMEOUT} + [ -z "${TO}" ] && TO=0 + [ "${TO}" -gt 0 ] || [ "${TO}" -lt 100 ] || TO=600 + [ "${TO}" -lt 0 ] && TO=0 + MIN=$(( TO / 60 )) + [ "$MIN" -gt 60 ] && MIN=60 + # Set + setterm -blank "$MIN" + setterm -powerdown "$MIN" + if [ "${TO}" = 0 ]; then + # Off + xset s "${TO}" "${TO}" + xset s off -dpms + else + xset +dpms + xset s "${TO}" "${TO}" + fi +} + +do_standby_stuff & +true + diff --git a/core/modules/screen-standby/module.build b/core/modules/screen-standby/module.build new file mode 100644 index 00000000..435a7b10 --- /dev/null +++ b/core/modules/screen-standby/module.build @@ -0,0 +1,13 @@ +fetch_source() { + : +} + +build() { + COPYLIST="list_dpkg_output" + list_packet_files > "$COPYLIST" + tarcopy "$(cat "${COPYLIST}" | sort -u)" "${MODULE_BUILD_DIR}" +} + +post_copy() { + : +} diff --git a/core/modules/screen-standby/module.conf b/core/modules/screen-standby/module.conf new file mode 100644 index 00000000..96ca18d4 --- /dev/null +++ b/core/modules/screen-standby/module.conf @@ -0,0 +1,5 @@ +REQUIRED_BINARIES=" +" +REQUIRED_LIBRARIES="" +REQUIRED_DIRECTORIES=" +" diff --git a/core/modules/smartctl/data/opt/openslx/scripts/systemd-smartctl b/core/modules/smartctl/data/opt/openslx/scripts/systemd-smartctl index 1eef0a23..979fde62 100755 --- a/core/modules/smartctl/data/opt/openslx/scripts/systemd-smartctl +++ b/core/modules/smartctl/data/opt/openslx/scripts/systemd-smartctl @@ -5,6 +5,7 @@ . /opt/openslx/config [ -z "$SLX_SMARTCTL_MIN_REALLOC" ] && SLX_SMARTCTL_MIN_REALLOC=0 +DELAY= FILES= for dev in /dev/sd?; do @@ -20,14 +21,21 @@ for dev in /dev/sd?; do # report if applicable if [ -n "$OVERALL" ]; then slxlog "smartctl-fail" "Failed HDD: $dev reports health as $OVERALL" "$FILE" + DELAY=yes fi if [ -n "$REALLOC" ] && [ "$REALLOC" -gt "$SLX_SMARTCTL_MIN_REALLOC" ]; then slxlog "smartctl-realloc" "Failing HDD: $dev has $REALLOC reallocated sectors!" "$FILE" + DELAY=yes fi if [ -n "$SPINRETRY_VAL" ] && [ "$SPINRETRY_VAL" -le "$SPINRETRY_THR" ]; then slxlog "smartctl-spinretry" "Failing HDD: $dev has bad spin retry count! ($SPINRETRY_VAL/$SPINRETRY_THR)" "$FILE" + DELAY=yes fi done -sleep 2 # give slxlog a little time, as it's running async + +[ -n "$DELAY" ] && sleep 2 # give slxlog a little time, as it's running async [ -n "$FILES" ] && rm -f -- $FILES # list, no "" +# Keep it that way instead of using --delete or --sync sonce it would add up; this way we're doing it just once here + +exit 0 diff --git a/core/modules/systemd-distro/module.build b/core/modules/systemd-distro/module.build index fa29a75f..8e5d3505 100644 --- a/core/modules/systemd-distro/module.build +++ b/core/modules/systemd-distro/module.build @@ -3,6 +3,10 @@ fetch_source () { } build () { + if ! which systemd >/dev/null; then + pwarning "No systemd binary found in PATH. " + perror "Make sure the system uses systemd before using this module." + fi COPYLIST="list_dpkg_output" [ -e "$COPYLIST" ] && rm "$COPYLIST" list_packet_files >> "$COPYLIST" diff --git a/core/modules/vbox/FIXME b/core/modules/vbox/FIXME new file mode 100644 index 00000000..849f08c2 --- /dev/null +++ b/core/modules/vbox/FIXME @@ -0,0 +1 @@ +Module does not work as of 07.12.2016, kernel module compile error. diff --git a/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/machine.include b/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/machine.include index 1f0b209a..344ccc48 100644 --- a/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/machine.include +++ b/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/machine.include @@ -11,10 +11,14 @@ # ----------------------------------------------------------------------------- # Include file (general template) for run-virt.include of the virtualbox plugin +# TODO: Move this server side (just like vmware) +# !! A lot of variable names have changed and are NOT updated here !! +# Oh and for the love of god remove the above comment when this works again + cat << EOF > "${machconfig}" <?xml version="1.0"?> <VirtualBox xmlns="http://www.innotek.de/VirtualBox-settings" version="1.14-linux"> - <Machine uuid="{${machineuuid}}" name="${vm_name}" OSType="${vmostype}"> + <Machine uuid="{${machineuuid}}" name="${VM_DISPLAYNAME}" OSType="${VM_OS_TYPE}"> <MediaRegistry> <HardDisks> <HardDisk uuid="{${diskuuid}}" location="${diskfile}" format="${imgfmt}" type="${imgtype}"/> diff --git a/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/run-virt.include b/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/run-virt.include index 1b116f32..59dd712d 100755 --- a/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/run-virt.include +++ b/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/run-virt.include @@ -14,261 +14,165 @@ # - component for virtualbox of the vmchooser plugin vmchooser-run_virt ################################################################################ +[ -r /run/hwinfo ] && source /run/hwinfo + ################################################################################ ### declaration of default variables ################################################################################ -VMCHOOSERVBOX="/opt/openslx/vmchooser/${self}" -confdir="${TMPDIR}/vbox" # dir for configs -export VBOX_USER_HOME=${confdir} # instead of $HOME/.VirtualBox -# define dirs and files which can be removed after exit, be carefull! -# TODO: Machanism not in use anymore. A better approach would be anyways to -# Define a fixed directory which can be deleted recursively on exit. $TMPDIR -# would be a start. -#RMDIRS="${snapshotdir} ${confdir} /tmp/virt/.vbox-${USER}-ipc" -# rm -rf ${RMDIRS} 2>/dev/null -machfolder="${confdir}/Machines" -# use vm_shortname for dir and config names since vm_name can be very long -machconfig="${machfolder}/${vm_shortname}/${vm_shortname}.xml" -diskfolder="${confdir}/HardDisks" -snapshotdir=${machfolder}/${vm_shortname}/Snapshots -mkdir -p ${diskfolder} ${snapshotdir} 2>/dev/null -[ -z "${diskless}" ] && diskless=0 # check if diskless var empty? -guestaudio="HDA" # default guest audio controller (SB16, AC97, HDA) -vb_network_card="82540EM" # default guest network adaptor (Am79C970A, Am79C973, 82540EM) +if ! isset VM_NAME_CLEAN IMG_BASENAME SRC_IMG_ABSOLUTE VM_OS_TYPE; then + env=$(mktemp) + env > "$env" + slxlog -d "virt-vbox-init" "A required variable is not set." "$env" + writelog "Incomplete variable set passed from main run-virt" + error_user "Wichtige variablen, die das VBox Plugin benötigt, wurden nicht +gesetzt. Kann die VM nicht starten." + cleanexit 1 +fi + +declare -rg VMCHOOSERVBOX="/opt/openslx/vmchooser/${self}" +declare -rg VBOX_ROOT="${TMPDIR}/vbox" # dir for configs +declare -rg VBOX_MACHINES_DIR="${VBOX_ROOT}/Machines" +declare -rg VBOX_SNAPSHOT_DIR="${VBOX_MACHINES_DIR}/${VM_NAME_CLEAN}/Snapshots" +declare -rg VBOX_HDD_DIR="${VBOX_ROOT}/HardDisks" +declare -rg VBOX_HDD_LINK="${VBOX_HDD_DIR}/${IMG_BASENAME}" + +export VBOX_USER_HOME="${VBOX_ROOT}" # instead of $HOME/.VirtualBox + +# use VM_NAME_CLEAN for dir and config names since VM_DISPLAYNAME can be very long +VBOX_MACHINE_CONFIG="${VBOX_MACHINES_DIR}/${VM_NAME_CLEAN}/${VM_NAME_CLEAN}.xml" +mkdir -p "${VBOX_HDD_DIR}" "${VBOX_SNAPSHOT_DIR}" 2>/dev/null enable2d="true" # default setting for accelerated 2D grapics (OS dependent) vram="128" # set default graphics ram +snapshotuuid="34f617be-192a-46b3-a8ae-bce1029e093f" # snapshot UUID is static -# configure our own rwimg, empty image which we provide -if [ "${imgmode}" = "rwimg" ]; then - imgname="${vm_shortname}.vdi" # what is our rwimg called? - vmpath=${imgpath}/${imgname} - if ! [ -e "${vmpath}" ]; then - cat /opt/openslx/vmchooser/virtualbox/rwimg.vdi.gz | gunzip > "${vmpath}" +# link to image, determine extension (type) +imgfmt=$(echo ${SRC_IMG_ABSOLUTE##*.} | tr '[a-z]' '[A-Z]') +if [ -n "$VM_DISKFILE_RW" ]; then + ln -sf "${VM_DISKFILE_RW}" "${VBOX_HDD_LINK}" +else + ln -sf "${VM_DISKFILE_RO}" "${VBOX_HDD_LINK}" + # image is RO, we only support VDI? + if [ "$imgfmt" != "VDI" ]; then + writelog "Image is not VDI, cannot create snapshot.." + error_log "Die gewählte VM nutzt VBox, hat aber kein VDI image (sondern '$imgfmt'), kann VM nicht starten." + cleanexit 1 fi fi -# link to image -diskfile="${diskfolder}/${imgname}" -[ ${diskless} -eq 0 ] && ln -sf ${vmpath} ${diskfile} - -# check the file type -if echo ${imgname} | grep -qiE "vdi|vhd" && [ ${diskless} -eq 0 ]; then - imgfmt=$(echo ${imgname##*.} | tr "[a-z]" "[A-Z]") -elif [ ${diskless} -eq 0 ]; then - writelog "${imgname} is not a valid image format (vdi|vhd), exiting!" - cleanexit 1 -fi - -npaging="false" # nested paging: Default: not enabled -enablevt="false" # VT: Default: not enabled -[ ${vtflag} -eq 0 ] && cpu_cores=1 # check for VT, if not available only 1 cpu supported -[ ${vtflag} -eq 1 ] && enablevt="true" # Setting some default variables shfolders="TRUE" +enablevt="true" # set some base configuration depending on the guest operating system -case "${vmostype}" in - win31*) - guestaudio="SB16" - vb_network_card="Am79C973" - vmostype="Windows31" +case "${VM_OS_TYPE}" in + Windows31) mem="32" vram="16" cpu_cores=1 enablevt="false" shfolders="FALSE" - ;; - winnt*) - guestaudio="SB16" - vb_network_card="Am79C973" - vmostype="Windows31" - mem="32" + ;; + WindowsNT) + mem="4096" vram="16" - cpu_cores=1 + cpu_cores=4 enablevt="false" shfolders="FALSE" - ;; - win95*) - vmostype="Windows95" - guestaudio="SB16" - vb_network_card="Am79C973" - mem="92" + ;; + Windows95) + mem="128" vram="32" cpu_cores=1 enablevt="false" shfolders="FALSE" - ;; - win98*) - vmostype="Windows98" - guestaudio="SB16" - vb_network_card="Am79C973" + ;; + Windows98) mem="256" vram="64" cpu_cores=1 shfolders="FALSE" - ;; - winme*) - vmostype="WindowsMe" - guestaudio="AC97" - vb_network_card="Am79C973" + ;; + WindowsMe) mem="256" vram="64" cpu_cores=1 shfolders="FALSE" - ;; - winxp*|windowsxp*) - vmostype="WindowsXP" - guestaudio="AC97" - ;; - winvista*|windowsvista*) - vmostype="WindowsVista" - ;; - windows7*) - vmostype="Windows7" - ;; - windows8*) - vmostype="Windows8" - ;; - linux*|*ubuntu*|*suse*|debian*|*sci*) - if echo "${vmostype}" | grep -q "64"; then - vmostype="Linux26_64" - # check for vtflag - if [ ${vtflag} -ne 1 ]; then - writelog "You are trying to boot a 64 bit OS without a VT enabled CPU" - writelog "This is not supported, exiting!" - cleanexit 1 - fi - # check if host is only 32 bit, then use only 1 cpu (only 1 supported) - if echo "${host_arch}" | grep -qE "i.86"; then - cpu_cores=1 - fi - else - vmostype="Linux26" - fi - ;; - os2*) + ;; + WindowsXP) + ;; + WindowsVista) + ;; + Windows7) + ;; + Windows8) + ;; + OS2eCS) mem="256" - vmostype="OS2eCS" cpu_cores=1 enable2d="false" - ;; - macos*|MacOS*) - vmostype="MacOS" + ;; + MacOS) enable2d="false" - ;; + ;; + Linux*) + ;; *) - vmostype="Other" + VM_OS_TYPE="Other" enable2d="false" - ;; + ;; esac +if [ "$HW_KVM" != "ENABLED" ]; then + enablevt="false" + cpu_cores=1 # check for VT, if not available only 1 cpu supported +fi + writelog "Directories:" -writelog "\tConfig dir:\t\t$confdir" -writelog "\tMachines dir:\t\t$machfolder" -writelog "\tMachine config:\t\t$machconfig" -[ ${diskless} -eq 0 ] && writelog "\tHardDisks dir:\t\t$diskfolder" +writelog "\tConfig dir:\t\t$VBOX_ROOT" +writelog "\tMachines dir:\t\t$VBOX_MACHINES_DIR" +writelog "\tMachine config:\t\t$VBOX_MACHINE_CONFIG" ################################################################################ ### Hardware checks ################################################################################ # remove ':' from MAC addr for vbox and generate a VDE (virtual device ethernet) -# MAC addr from the first one (put in prefix 0DE) +# MAC addr from the first one (put in prefix 00DE) macaddr=$(echo ${macaddr} | sed 's/://g') vdemacaddr=$(echo ${macaddr} | sed 's/^..../00DE/g') machineuuid="00000000-0000-0000-0000-${macaddr}" # machine UUID, MAC addr part of it machineuuid=$(echo ${machineuuid} | tr "[A-Z]" "[a-z]") # cosmetical, since UUID in lower case -# get UUID of VBox image, if not diskless -[ ${diskless} -eq 0 ] && diskuuid=$(VBoxManage -q showvdiinfo ${diskfile} \ - | grep UUID | grep -v "Parent UUID" | awk '{print $2}' \ - | grep -v use ) # nec. for VBox >= 4 -imgtype="Immutable" # make disk immutable -snapshotuuid="34f617be-192a-46b3-a8ae-bce1029e093f" # snapshot UUID is static -imageuuid=${snapshotuuid} # imageuuid in machine.include, default snapshotuuid - -# check if rw image -# remove disk and add rwimg if set -if echo "${imgmode}" | grep -q rw; then - # lock existing? - if [ -e "${vmpath}.lock" ]; then - writelog "This rw image is already in use." - writelog "Found lock: ${vmpath}.lock, exiting!" - writelog "Remove lock if you are sure that this is not the case" - cleanexit 1 - # image rw? - elif ! [ -w ${vmpath} ]; then - writelog "You defined mode rw, but image ${vmpath} is not rw! \c" - writelog "Please correct, exiting!" - cleanexit 1 - fi - touch "${vmpath}.lock" # add lock - #RMDIRS="${RMDIRS} ${vmpath}.lock" # remove lock after VM stopped TODO See note at the top +# get UUID of VBox image +diskuuid=$(VBoxManage -q showvdiinfo ${VBOX_HDD_LINK} \ + | grep UUID | grep -v "Parent UUID" | awk '{print $2}' \ + | grep -v use ) # nec. for VBox >= 4 + + +if [ -n "$VM_DISKFILE_RW" ]; then + # Image is already RW - easy imgtype="Normal" - imageuuid=${diskuuid} # replace image uuid in machine config -elif [ ${diskless} -eq 0 ]; then - # use temp disk as snapshot - cat ${VMCHOOSERVBOX}/empty-diff.vdi.gz \ - | gunzip > "${snapshotdir}/{${snapshotuuid}}.vdi" - # patch the disk file uuid into the snapshot vdi file - dd if=${diskfile} of="${snapshotdir}/{${snapshotuuid}}.vdi" seek=424 \ - skip=392 bs=1 count=16 conv=notrunc + imageuuid=${diskuuid} +else + # use temp disk as snapshot to get CoW + imgtype="Immutable" # make disk immutable + imageuuid=${snapshotuuid} + < "${VMCHOOSERVBOX}/empty-diff.vdi.gz" gunzip > "${VBOX_SNAPSHOT_DIR}/{${snapshotuuid}}.vdi" + # patch the disk file uuid into the snapshot vdi file: + # We read from offset 424 in the source HDD and write to offset 392 in out prepared + # CoW container. 16 bytes will be copied, which is the binary UUID + # TODO: This requires the image to be a vdi/vdh; Afaik, vbox supports vmdk, + # so this code would break in that case. Can we use the diskuuid we got via + # VBoxManage, convert to binary, and patch it + dd if=${VBOX_HDD_LINK} of="${VBOX_SNAPSHOT_DIR}/{${snapshotuuid}}.vdi" seek=424 \ + skip=392 bs=16 count=1 conv=notrunc fi -# TODO: MEM muss noch angepasst werden. Maschine crasht wenn mehr als 50% MEM -# memory part equal to vmware plugin -# percentage of memory to use for virtualbox in standard case -#if [ -n "${forcemem}" ]; then -# mem="${forcemem}" -#else -# permem=30 -# if [ "${totalmem}" -ge "1600" ]; then -# permem=40 -# fi -# # check if /tmp is on harddisk -# if grep -qe "/dev/.* /tmp " /proc/mounts ; then -# permem=60 -# id44="1" -# # Hack, if more than 2,5G RAM use 40% of Ram and write vmem into Ram as well -# # (40% vmware | 40% confdir(vmem...) | 20% host -# # VMplayer 2+ issue -# # TODO: makes this sense for vbox? -# #if [ "${totalmem}" -ge "2500" ]; then -# #permem=40 -# #rmdir ${snapshotdir} -# #snapshotdirold=${snapshotdir} -# #snapshotdir=/dev/shm/${self}/${USER}/${VM_ID} -# #mkdir -p ${snapshotdir} -# #ln -sf ${snapshotdir} ${snapshotdirold} -# #fi -# fi -# mem=$(expr ${totalmem} / 100 \* ${permem}) -# if [ "${id44}" = "1" ]; then -# hostmem=$(expr ${totalmem} - ${mem}) -# else -# hostmem=$(expr ${totalmem} - ${mem} - ${mem}) -# fi -# #permem=40 -# #mem=$(expr ${totalmem} * ${permem}) -#fi - -# translate network cards -case "${network_card}" in - e1000) - vb_network_card="82540EM" - ;; - virtio) - vb_network_card="virtio" - ;; - *) - network_card="pcnet" - vb_network_card="Am79C973" -esac - # translate network kinds (nat, bridged, host-only) +# TODO: Server should prepare this in returned xml case "${network_kind}" in bridge*) network_kind='HostOnlyInterface name="vboxnet0"' @@ -280,57 +184,19 @@ case "${network_kind}" in network_kind='HostOnlyInterface name="vboxnet1"' esac -# configure 3d settings -case "${enable3d}" in - *true*|*yes*) - enable3d="true" - ;; - *) - enable3d="false" - ;; -esac +boot="HardDisk" -# translate boot, use if set else set to HardDisk -# usually support for a,c,d,n, stands for Floppy, HD, CD-ROM, Network -# support nfs and tftp as well -case ${boot} in - n*|tftp) - boot="Network" - if [ "${network_kind}" = "NAT" ] && [ -n "${virtualbox_tftpdir}" ]; then - vm_name=${vm_shortname} # use vm_shortname to avoid Problems /w TFTP in NAT - mkdir -p ${confdir}/TFTP # link TFTP dir for NAT TFTP boots - if [ -e ${virtualbox_tftpdir}/pxelinux.0 ]; then - cp ${virtualbox_tftpdir}/pxelinux.0 ${confdir}/TFTP/${vm_name}.pxe - else - writelog "${virtualbox_tftpdir}/pxelinux.0 not found!" - writelog "Network boot won't work, exiting!" - cleanexit 1 - fi - for i in $(ls ${virtualbox_tftpdir}); do - ln -sf ${virtualbox_tftpdir}/${i} ${confdir}/TFTP/${i} - done - fi - ;; - # later maybe c|disk|hd*|sd*) for HD and d|cd*) for CD-ROM - *) - boot="HardDisk" - ;; -esac - -vrdpport=${remotedesktopport} # external GUI - -[ ${diskless} -eq 0 ] && writelog "\tSnapshots dir:\t\t$snapshotdir" +writelog "\tSnapshots dir:\t\t$VBOX_SNAPSHOT_DIR" writelog "Diskimage:" -[ ${diskless} -eq 0 ] && writelog "\tDisk file:\t\t$diskfile" -[ ${diskless} -eq 0 ] && writelog "\tDisk format:\t\t$imgfmt" -[ ${diskless} -eq 0 ] && writelog "\tDisk type:\t\t$imgtype" - writelog "\tVMostype:\t\t$vmostype" - writelog "\tMachine UUID:\t\t$machineuuid" -[ ${diskless} -eq 0 ] && writelog "\tDisk UUID:\t\t$diskuuid" +writelog "\tDisk file:\t\t$VBOX_HDD_LINK" +writelog "\tDisk type:\t\t$imgtype" +writelog "\tVMostype:\t\t$VM_OS_TYPE" +writelog "\tMachine UUID:\t\t$machineuuid" +writelog "\tDisk UUID:\t\t$diskuuid" writelog "Virtual Hardware:" writelog "\tCPU cores:\t\t${cpu_cores}\c" -[ ${vtflag} -eq 0 ] && writelog "" -[ ${vtflag} -eq 1 ] && writelog " (VT enabled CPU)" +writelog "" +[ "$HW_KVM" = "ENABLED" ] && writelog " (VT enabled CPU)" writelog "\tGuest RAM:\t\t${mem} MB" # echo nur wenn hostmem gesetzt [ -n "${hostmem}" ] && writelog "\tHost RAM:\t\t${hostmem} MB" @@ -338,10 +204,7 @@ writelog "\tMAC address:\t\t$macaddr" writelog "\tNetwork card:\t\t${vb_network_card}" writelog "\tNetwork kind:\t\t${network_kind}" writelog "\tBooting from:\t\t${boot}\c" -[ ${diskless} -eq 0 ] && writelog "" -[ ${diskless} -eq 1 ] && writelog " 'diskless'" -# TODO: server start activate via xml, etc... -#writelog "\tGuest VRDP port:\t${vrdpport}" +writelog "" writelog "\tCD-ROM1:\t\t${cdrom0}" #writelog "\tCD-ROM2:\t\t${cdrom1}" writelog "\tFloppy_A:\t\t${floppy0}" @@ -357,60 +220,31 @@ writelog "\tShared Folders '${sharename}':\t${sharepath}" # Shares given? if [ "x$shfolders" != "xFALSE" ]; then - sharelist="<SharedFolders> + sharelist="<SharedFolders> <SharedFolder name=\"${homesharename}\" hostPath=\"${homesharepath}\" writable=\"true\"/> <SharedFolder name=\"${commonsharename}\" hostPath=\"${commonsharepath}\" writable=\"true\"/> </SharedFolders>" else - sharelist='' + sharelist='' fi -source ${VMCHOOSERVBOX}/virtualbox.include # create Virtualbox.xml +source "${VMCHOOSERVBOX}/virtualbox.include" # create Virtualbox.xml # remove snapshot disk when using rw images if [ "${imgtype}" != "Immutable" ]; then - sed -i "/${snapshotuuid}/d" "${confdir}/VirtualBox.xml" + sed -i "/${snapshotuuid}/d" "${VBOX_ROOT}/VirtualBox.xml" fi # TODO: add rawdisk if requested #"raw.vmdk" format="VMDK" type="Writethrough"/> -source ${VMCHOOSERVBOX}/machine.include # create machine.xml +source "${VMCHOOSERVBOX}/machine.include" # create machine.xml # remove CD-ROM if not available if [ "${cdrom0}" != "TRUE" ]; then - sed -i "/HostDrive/d" ${machconfig} - sed -i '/AttachedDevice.*type="DVD"/d' ${machconfig} - sed -i "/<!-- PLEASE DO NOT REMOVE THIS COMMENT (CD)!!! -->/d" ${machconfig} -fi - -# if diskless remove all disks -if [ ${diskless} -eq 1 ]; then - sed -i "/<HardDisk/d;/<\/HardDisk/d" "${confdir}/VirtualBox.xml" - sed -i "/${imageuuid}/d" ${machconfig} - sed -i '/AttachedDevice type="HardDisk"/d' ${machconfig} - sed -i "/<!-- PLEASE DO NOT REMOVE THIS COMMENT (HD)!!! -->/d" ${machconfig} -fi - -# define redirects -if [ ${redirects} -ge 1 ]; then - (( i=1 )) - writelog "\tGuest redirects:\t\c" - while [ ${i} -le ${redirects} ]; do - extradataitem='<ExtraDataItem name="VBoxInternal/Devices' - extradataitem="${extradataitem}/${network_card}/0/LUN#0/Config" - extradataitem="${extradataitem}/${redirect_name[$i]}/" - extradataprotocol="Protocol\" value=\"${redirect_proto[$i]}\"/>" - extradatahostport="HostPort\" value=\"${redirect_hport[$i]}\"/>" - extradataguestport="GuestPort\" value=\"${redirect_gport[$i]}\"/>" - sed -i "s,</ExtraData>, ${extradataitem}${extradataguestport}\n\ - ${extradataitem}${extradatahostport}\n\ - ${extradataitem}${extradataprotocol}\n\ - </ExtraData>," "${machconfig}" - writelog "${tabspace}${redirect_name[$i]} port: ${redirect_hport[$i]}" - tabspace='\t\t\t\t' - (( i=$i+1 )) - done + sed -i "/HostDrive/d" "${VBOX_MACHINE_CONFIG}" + sed -i '/AttachedDevice.*type="DVD"/d' "${VBOX_MACHINE_CONFIG}" + sed -i "/<!-- PLEASE DO NOT REMOVE THIS COMMENT (CD)!!! -->/d" "${VBOX_MACHINE_CONFIG}" fi ################################################################################ diff --git a/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/virtualbox.include b/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/virtualbox.include index 62143c54..70a036a8 100644 --- a/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/virtualbox.include +++ b/core/modules/vbox/data/opt/openslx/vmchooser/virtualbox/virtualbox.include @@ -11,7 +11,7 @@ # ----------------------------------------------------------------------------- # Include file (general template) for run-virt.include of the virtualbox plugin -cat << EOF > "${confdir}/VirtualBox.xml" +cat << EOF > "${VBOX_ROOT}/VirtualBox.xml" <VirtualBox xmlns="http://www.innotek.de/VirtualBox-settings" version="1.12-linux"> <Global> <ExtraData> @@ -27,7 +27,7 @@ cat << EOF > "${confdir}/VirtualBox.xml" <ExtraDataItem name="GUI/TrayIcon/Enabled" value="false"/> </ExtraData> <MachineRegistry> - <MachineEntry uuid="{${machineuuid}}" src="Machines/${vm_shortname}/${vm_shortname}.xml"/> + <MachineEntry uuid="{${machineuuid}}" src="Machines/${VM_NAME_CLEAN}/${VM_NAME_CLEAN}.xml"/> </MachineRegistry> <MediaRegistry> <HardDisks> diff --git a/core/modules/vbox/module.conf b/core/modules/vbox/module.conf index a2925bc7..e2e9040f 100644 --- a/core/modules/vbox/module.conf +++ b/core/modules/vbox/module.conf @@ -4,9 +4,14 @@ # REQUIRED_VBOX_VERSIONCODE="101573" # VBox version 4 last branch: -REQUIRED_VBOX_VERSION_MAJOR="5.0" -REQUIRED_VBOX_VERSION_MINOR="16" -REQUIRED_VBOX_VERSIONCODE="105871" +REQUIRED_VBOX_VERSION_MAJOR="4.3" +REQUIRED_VBOX_VERSION_MINOR="26" +REQUIRED_VBOX_VERSIONCODE="98988" + +# TODO: retest ssc's test with +#REQUIRED_VBOX_VERSION_MAJOR="5.0" +#REQUIRED_VBOX_VERSION_MINOR="16" +#REQUIRED_VBOX_VERSIONCODE="105871" REQUIRED_VBOX_VERSION="$REQUIRED_VBOX_VERSION_MAJOR.$REQUIRED_VBOX_VERSION_MINOR" diff --git a/core/modules/vmchooser2/data/opt/openslx/bin/vmchooser b/core/modules/vmchooser2/data/opt/openslx/bin/vmchooser index a99207ff..2588c884 100755 --- a/core/modules/vmchooser2/data/opt/openslx/bin/vmchooser +++ b/core/modules/vmchooser2/data/opt/openslx/bin/vmchooser @@ -5,6 +5,7 @@ # /opt/openslx/config, as well as the pool filter (if any) . /opt/openslx/config +unset MEM URL ERRMSG EXTRA TAB HW_MBRAM HW_ID44 if [ -n "$SLX_VMCHOOSER_BASE_URL" ]; then URL="$SLX_VMCHOOSER_BASE_URL" @@ -12,25 +13,38 @@ elif [ -n "$SLX_PXE_SERVER_IP" ]; then URL="http://$SLX_PXE_SERVER_IP/vmchooser/" else slxlog "virt-vmchooser" "vmchooser: Could not determine URL to fetch VM list from! (need SLX_VMCHOOSER_BASE_URL)" - # TODO: Tell user + ERRMSG="Keine URL zum Abrufen der verfügbaren Veranstaltungen definiert. Versuchen Sie, den Computer neu zu starten und wenden Sie sich an den Support, wenn das Problem weiterhin besteht." + /opt/openslx/cups/printergui --error "$ERRMSG" || notify-send "Fehler" "$ERRMSG" +fi + +. "/run/hwinfo" +if [ -z "$HW_MBRAM" ]; then + MEM=$(grep -m1 '^MemTotal:' /proc/meminfo | awk '{print $2}') + HW_MBRAM=$(( MEM / 1024 )) +fi +# No/small ID44 = penalty to available ram +if [ -n "$HW_ID44" ] && ! [ "$HW_ID44" -gt 9000 ]; then # Use negation so NaN -> TRUE + HW_MBRAM=$(( ( HW_MBRAM * 3 ) / 4 )) fi -MEM=$(grep -m1 '^MemTotal:' /proc/meminfo | awk '{print $2}') if [ -n "$SLX_VMCHOOSER_TAB" ] && [ "$SLX_VMCHOOSER_TAB" -ge 0 -a "$SLX_VMCHOOSER_TAB" -le 2 ] 2>/dev/null; then TAB="$SLX_VMCHOOSER_TAB" -elif [ "$MEM" -lt 3000000 ]; then # Check RAM size; if it's not that much, default to the native linux sessions +elif [ "$HW_MBRAM" -lt 3000 ]; then # Check RAM size; if it's not that much, default to the native linux sessions TAB=0 else TAB=2 fi -EXTRA= [ -n "$SLX_VMCHOOSER_TEMPLATES" ] && EXTRA="$EXTRA --template-mode $SLX_VMCHOOSER_TEMPLATES" [ -n "$SLX_VMCHOOSER_FORLOCATION" ] && EXTRA="$EXTRA --location-mode $SLX_VMCHOOSER_FORLOCATION" +[ "$HW_KVM" != "ENABLED" ] && EXTRA="$EXTRA --no-vtx" +[ -n "$SLX_EXAM" ] && EXTRA="$EXTRA --exam-mode" +# No quotes around $EXTRA! if [ -z "$SLX_LOCATIONS" ]; then - exec vmchooser.real "$@" --url "$URL" --fullscreen --tab "$TAB" $EXTRA + exec vmchooser.real "$@" --url "$URL" --fullscreen --tab "$TAB" --start-uuid "$SLX_EXAM_START" $EXTRA fi -exec vmchooser.real "$@" --url "$URL" --fullscreen --tab "$TAB" --locations "$SLX_LOCATIONS" $EXTRA +# No quotes around $EXTRA! +exec vmchooser.real "$@" --url "$URL" --fullscreen --tab "$TAB" --start-uuid "$SLX_EXAM_START" --locations "$SLX_LOCATIONS" $EXTRA diff --git a/core/modules/vmchooser2/data/opt/openslx/vmchooser/sessionstart.d/log-selected-session b/core/modules/vmchooser2/data/opt/openslx/vmchooser/sessionstart.d/log-selected-session index 2499b3b7..fb8ae9eb 100755 --- a/core/modules/vmchooser2/data/opt/openslx/vmchooser/sessionstart.d/log-selected-session +++ b/core/modules/vmchooser2/data/opt/openslx/vmchooser/sessionstart.d/log-selected-session @@ -1,5 +1,16 @@ #!/bin/ash -[ -n "$SESSION_NAME" ] && slxlog ".vmchooser-session-name" "$SESSION_NAME" +[ -z "${SESSION_UUID}${SESSION_NAME}" ] && exit 0 + +. /opt/openslx/config + +[ -z "$SLX_REMOTE_LOG" ] && exit 0 + +REALUSER=$(whoami) +LOGUSER=0 +[ "x$SLX_REMOTE_LOG_SESSIONS" = "xyes" ] && LOGUSER=1 + +curl --data-urlencode "type=.vmchooser-session" --data-urlencode "uuid=$SESSION_UUID" --data-urlencode "name=$SESSION_NAME" \ + --data-urlencode "user=$REALUSER" --data-urlencode "loguser=$LOGUSER" "$SLX_REMOTE_LOG" exit 0 diff --git a/core/modules/vmchooser2/module.build b/core/modules/vmchooser2/module.build index 3686aa75..4a6d56c4 100644 --- a/core/modules/vmchooser2/module.build +++ b/core/modules/vmchooser2/module.build @@ -1,6 +1,6 @@ fetch_source() { - git clone "${REQUIRED_GIT}" src + git clone "${REQUIRED_GIT}" "${MODULE_WORK_DIR}/src" } build() { diff --git a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/create_static_directory_structure.inc b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/create_static_directory_structure.inc new file mode 100644 index 00000000..96363de3 --- /dev/null +++ b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/create_static_directory_structure.inc @@ -0,0 +1,23 @@ +############################### +# Include: Write config files # +############################### + +writelog "Redo directory: ${redodir}" +writelog "Config directory: ${confdir}" +writelog "Config file: ${conffile}" +writelog "vmhome/dndlogs: ${vmhome}/dndlogs" + +# create vmware directories +mkdir -p "$redodir" >/dev/null 2>&1 +mkdir -p "$confdir" >/dev/null 2>&1 +mkdir -p "$vmhome/dndlogs" >/dev/null 2>&1 +touch "$vmhome/dndlogs/dndlog.conf" >/dev/null 2>&1 + +# link to conffile if confdir != redodir +[ "$confdir" != "$redodir" ] && ln -s "$conffile" "$redodir/run-vmware.conf" >/dev/null 2>&1 + +# own nvram. We need it for floppy drive b, default nvram has just drive a +if ! cp "/opt/openslx/vmchooser/vmware/nvram" "$confdir/nvram"; then + slxlog "virt-vmware-nvram" "Could not copy nvram from '/opt/openslx/vmchooser/vmware/nvram' '$confdir/nvram'" +fi + diff --git a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/create_vmhome_preferences_file.inc b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/create_vmhome_preferences_file.inc index b618041c..d50402f3 100644 --- a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/create_vmhome_preferences_file.inc +++ b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/create_vmhome_preferences_file.inc @@ -68,4 +68,5 @@ create_vmhome_preferences_file() { echo 'pref.hotkey.rightControl = "true"' >> "$vmhome/preferences" fi writelog "Vmware preferences file created in $vmhome." + true } diff --git a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/determine_hardware_limitations.inc b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/determine_hardware_limitations.inc new file mode 100644 index 00000000..11ea2e3a --- /dev/null +++ b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/determine_hardware_limitations.inc @@ -0,0 +1,185 @@ +######################################## +# Include: Determine hw limitations depending on hwver and guest os # +######################################## + +MAXMEM="9999999" +MAXCORES="4" +shfolders="TRUE" +sound="es1371" + +# define hardware configuration depending on the guest OS used +# this needs to be fixed and is the base for the creation of new VMs +case "$VM_OS_TYPE" in + win31*|windows31*) + VM_OS_TYPE="win31" + shfolders="FALSE" + sound="sb16" + MAXMEM="32" + MAXCORES="1" + ;; + winnt*|windowsnt*) + VM_OS_TYPE="winnt" + shfolders="FALSE" + sound="sb16" + MAXMEM="1000" + MAXCORES="2" + ;; + win95*|windows95*) + VM_OS_TYPE="win95" + shfolders="FALSE" + MAXMEM="96" + MAXCORES="1" + ;; + win98*|windows98*) + VM_OS_TYPE="win98" + MAXMEM="256" + MAXCORES="1" + ;; + winme*|windowsme*) + VM_OS_TYPE="winme" + MAXMEM="384" + MAXCORES="1" + ;; + win2000|windows2000|win2000pro*) + VM_OS_TYPE="win2000pro" + MAXMEM="4000" + MAXCORES="2" + ;; + win2000srv*|windows2000srv*|win2000serv*|windows2000serv*) + VM_OS_TYPE="win2000serv" + shfolders="FALSE" + MAXMEM="4000" + MAXCORES="4" + ;; + win2000adv*|windows2000adv*|win2000dat*|windows2000dat*) + VM_OS_TYPE="win2000advserv" + shfolders="FALSE" + MAXMEM="8000" + MAXCORES="8" + ;; + winnet*64|win*2003*64|windowsnet*64) + VM_OS_TYPE="winnetstandard-64" + MAXMEM="8000" + MAXCORES="8" + ;; + winnet*|win*2003*|windowsnet*) + VM_OS_TYPE="winnetstandard" + MAXMEM="4000" + MAXCORES="8" + ;; + winxphome*|windowsxphome*) + VM_OS_TYPE="winxphome" + MAXMEM="4000" + MAXCORES="2" + ;; + winxp*64|windowsxp*64) + VM_OS_TYPE="winxppro-64" + MAXMEM="8000" + MAXCORES="8" + ;; + winxp*|windowsxp*) + VM_OS_TYPE="winxppro" + MAXMEM="4000" + MAXCORES="4" + ;; + winvista-64) + VM_OS_TYPE="winvista-64" + MAXMEM="16000" + MAXCORES="4" + ;; + windows7-64) + VM_OS_TYPE="windows7-64" + MAXMEM="32000" + MAXCORES="8" + ;; + windows8-64) + VM_OS_TYPE="windows8-64" + MAXMEM="32000" + MAXCORES="8" + ;; + windows9-64) + VM_OS_TYPE="windows9-64" + MAXMEM="64000" + MAXCORES="8" + ;; + winvista) + VM_OS_TYPE="winvista" + MAXMEM="8000" + MAXCORES="2" + ;; + windows7) + VM_OS_TYPE="windows7" + MAXMEM="8000" + MAXCORES="4" + ;; + windows8) + VM_OS_TYPE="windows8" + MAXMEM="8000" + MAXCORES="4" + ;; + windows9) + VM_OS_TYPE="windows9" + MAXMEM="8000" + MAXCORES="4" + ;; + win*64) + MAXMEM="16000" + MAXCORES="4" + ;; + win*) + MAXMEM="8000" + MAXCORES="1" + ;; + dos|msdos*|ms-dos*) + VM_OS_TYPE="dos" + shfolders="FALSE" + MAXMEM="128" + MAXCORES="1" + ;; + macos*64) + VM_OS_TYPE="freebsd-64" + MAXMEM="4000" + MAXCORES="2" + ;; + macos*) + VM_OS_TYPE="freebsd" + MAXMEM="4000" + MAXCORES="1" + ;; + beos*) + VM_OS_TYPE="other" + shfolders="FALSE" + ;; + # Unknown guestOS setting in .xml - this encompasses linux too, + # as there is a multitude of different distributions. Perhaps further + # action will be needed if this leads to problems with exotic OSs. + *64) + VM_OS_TYPE="other-64" + # shfolders="FALSE" + MAXMEM="123456" + MAXCORES="4" + ;; + *) + VM_OS_TYPE="other" + # shfolders="FALSE" + MAXMEM="8000" + MAXCORES="1" + ;; +esac + +real_core_count="$cpu_cores" +[ "$cpu_cores" -gt "$MAXCORES" ] && cpu_cores="$MAXCORES" + +# It currently makes no sense to set the virtual number of cores +# to a different value than the virtual number of cores per virtual CPU. +cores_per_socket="$cpu_cores" + +if [ "x$shfolders" != "xFALSE" ] && [ "$SHARE_REMAP_MODE" != 1 ]; then + HGFS_DISABLED="FALSE" +else + HGFS_DISABLED="TRUE" +fi + +[ "$mem" -ge "$MAXMEM" ] && mem="$MAXMEM" +[ "$HWVER" -lt "7" -a "$mem" -gt "3500" ] && mem="3500" + diff --git a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/log_config_summary.inc b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/log_config_summary.inc new file mode 100644 index 00000000..41986b2a --- /dev/null +++ b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/log_config_summary.inc @@ -0,0 +1,60 @@ +################################################## +# Include: Print vm config summary into log file # +################################################## + +# log script information +writelog "# File created by $0 (VMware version ${vmware_version})\n# on $(date)\n" +## Edited for persistent mode. +writelog "Starting with ${diskmode} mode ...\n" +## + +# write all results to logfile +# log disksetup +writelog "Directories:" +writelog "\tConfdir:\t${confdir}" +writelog "\tConffile:\t${conffile}" +writelog "\tRedodir:\t${redodir}" +writelog "\tVMhome:\t\t${vmhome}" +writelog "\t/tmp info: $(grep "/tmp " /proc/mounts) $(df -h | grep " /tmp$" | awk '{print $2}')" +# hw setup +writelog "Hardware:" +writelog "\tMAC:\t\t$macaddr" +if [ -n "${network_card}" ]; then + writelog "\tNet Adaptor:\t${network_card}" +fi +writelog "\tMem:\t\t${mem} MB" + +# echo nur wenn hostmem gesetzt +[ -n "${hostmem}" ] && writelog "\tHostmem:\t${hostmem} MB" +writelog "\tCD-ROM1:\t${cdrom0}" +writelog "\tCD-ROM2:\t${cdrom1}" +writelog "\tFloppy_A:\t${floppy0}" +if [ "${serial}" = "TRUE" ]; then + writelog "\tSerial Port:\t${serialdev}" +fi +if [ "${parallel}" = "TRUE" ]; then + writelog "\tParallel Port:\t${paraldev}" +fi + +writelog "Shared folders:" +if [ "${HGFS_DISABLED}" = "FALSE" ]; then + writelog "\tNo shared folders enabled." +else + writelog "\Shared folders enabled." +fi + +# image +writelog "Diskimage:" +writelog "\tDiskfile:\t${VM_DISKFILE_RO}" +writelog "\tHWVersion:\t${HWVER}" +writelog "\tVMostype:\t${VM_OS_TYPE}" + +# misc +writelog "Misc:" +writelog "\tDisplayname:\t${VM_DISPLAYNAME}" +if [ "${cap3d}" = "TRUE" -a "${enable3d}" = "TRUE" ]; then + writelog "\t3D Graphics:\tenabled" +fi +# empty line at end +writelog "" + diff --git a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/parse_vmx.inc b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/parse_vmx.inc index 092abce5..dec80e1d 100644 --- a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/parse_vmx.inc +++ b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/parse_vmx.inc @@ -1,130 +1,8 @@ ###################################################################### -# Include: Parsing the non-legacy delivered vmxfile $TMPDIR/$IMGUUID # +# Include: Parsing the non-legacy delivered vmxfile ${TMPCONFIG} # ###################################################################### writelog "Parsing virtual machine description file..." -# check for vmdk file marker %VM_DISK_PATH% and put vmdk path in it's place: also VM_DISK_MODE -# and VM_DISK_REDOLOGDIR. -# IMAGE=$(grep -io '<image_path.*"' "${xmlfile}" | sed -e "s/&.*;/; /g" | awk -F '"' '{ print $2 }') -sed -i 's#%VM_DISK_PATH%#'"$vm_diskfile"'#g' "$TMPDIR/$IMGUUID" -sed -i 's#%VM_DISK_MODE%#'"independent-nonpersistent"'#g' "$TMPDIR/$IMGUUID" -sed -i 's#%VM_DISK_REDOLOGDIR%#'"$redodir"'#g' "$TMPDIR/$IMGUUID" - -# Ethernet: All we do is entering a generated MAC, as we do not want to interfere -# in the possible case no networking is wanted. -writelog "Guest MAC: $macaddr" -echo 'ethernet0.addressType = "static"' >> "$TMPDIR/$IMGUUID" -echo 'ethernet0.address = "'"${macaddr}"'"' >> "$TMPDIR/$IMGUUID" - -# DVD, CDROM -# XXX: For now it's save to assume ide channel 1 is free, as we support only one HDD, and it it's IDE, it's on channel 0 -cat >> "$TMPDIR/$IMGUUID" <<-HEREEND -ide1:0.present = "$cdrom0" -ide1:0.autodetect = "TRUE" -ide1:0.fileName = "auto detect" -ide1:0.deviceType = "cdrom-raw" -ide1:1.present = "$cdrom1" -ide1:1.autodetect = "TRUE" -ide1:1.fileName = "auto detect" -ide1:1.deviceType = "cdrom-raw" -HEREEND - -# Floppies: -cat >> "$TMPDIR/$IMGUUID" <<-HEREEND -floppy0.present = "$floppy0" -floppy0.startConnected = "FALSE" -floppy0.autodetect = "TRUE" -floppy0.fileName = "auto detect" -floppy1.present = "$floppy1" -floppy1.startConnected = "TRUE" -floppy1.fileType = "file" -floppy1.fileName = "$floppy1name" -HEREEND - -writelog "numvcpus = ${cpu_cores} - maxvcpus=${real_core_count}" - -# RAM, CPUs -cat >> "$TMPDIR/$IMGUUID" <<-HEREEND -numvcpus = "$cpu_cores" -cpuid.coresPerSocket = "$cores_per_socket" -maxvcpus = "$real_core_count" -memsize = "$mem" -MemAllowAutoScaleDown = "FALSE" -MemTrimRate = "-1" -HEREEND - -# USB -if [ -n "$SLX_EXAM" ]; then - # Exam mode: No USB (TODO: Configurable) - sed -i '/^usb\./d' "$TMPDIR/$IMGUUID" - echo 'usb.present = "FALSE"' >> "$TMPDIR/$IMGUUID" -else - cat >> "$TMPDIR/$IMGUUID" <<-HEREEND - usb.present = "TRUE" - usb.generic.autoconnect = "TRUE" - HEREEND -fi - -# shared folders -cat >> "$TMPDIR/$IMGUUID" <<-HEREEND -$ENABLE_SHARE -sharedFolder0.present = "$shfolders" -sharedFolder0.enabled = "$shfolders" -sharedFolder0.expiration = "never" -sharedFolder0.guestName = "$homesharename" -sharedFolder0.hostPath = "$homesharepath" -sharedFolder0.readAccess = "TRUE" -sharedFolder0.writeAccess = "TRUE" -sharedFolder1.present = "$shfolders" -sharedFolder1.enabled = "$shfolders" -sharedFolder1.expiration = "never" -sharedFolder1.guestName = "$commonsharename" -sharedFolder1.hostPath = "$commonsharepath" -sharedFolder1.readAccess = "TRUE" -sharedFolder1.writeAccess = "FALSE" -sharedFolder.maxNum = "2" -hgfs.mapRootShare = "TRUE" -hgfs.linkRootShare = "TRUE" -HEREEND - -# Isolation tools: settings -# It should be verified whether and when entries necessary -cat >> "$TMPDIR/$IMGUUID" <<-HEREEND -isolation.tools.hgfs.disable = "FALSE" -isolation.tools.dnd.disable = "FALSE" -isolation.tools.copy.enable = "TRUE" -isolation.tools.paste.enabled = "TRUE" -HEREEND - -# Serial, parallel: Empty, nothing is being currently set. TODO later. - -# Graphics, GPU: 3D will be enabled (even if vmware doesn't support the chip) if we whitelisted it. -if [ -n "$SLX_VMWARE_3D" ]; then - writelog "FORCE3D set - overriding 3D in vmx file." - echo 'mks.gl.allowBlacklistedDrivers = "TRUE"' >> "$TMPDIR/$IMGUUID" - # We override... play safe and cap the hwVersion to 10, since some i915 chips goofed up with 12 - # Investigate if we might have to do this in other cases where we don't override - if grep -qi '^mks.enable3d.*true' "$TMPDIR/$IMGUUID"; then - vmw_cap_hw_version "10" - fi -else - writelog "FORCE3D not set - 3D will only work if GPU/driver is whitelisted by vmware." -fi - -# Disable DPI scaling information passing via vmware tools -sed -i '/^gui.applyHostDisplayScaling/d' "$TMPDIR/$IMGUUID" -echo 'gui.applyHostDisplayScalingToGuest = "FALSE"' >> "$TMPDIR/$IMGUUID" - -# Additinal exam mode settings -if [ -n "$SLX_EXAM" ]; then - echo 'gui.restricted = "true"' >> "$TMPDIR/$IMGUUID" -fi - -# Killing duplicate lines (output much nicer than sort -u): -awk '!a[$0]++' "${TMPDIR}/${IMGUUID}" > "${TMPDIR}/${IMGUUID}.tmp" && mv "${TMPDIR}/${IMGUUID}.tmp" "${TMPDIR}/${IMGUUID}" - -# At last_ Let's copy it to $confdir/run-vmware.conf -cp -p "$TMPDIR/$IMGUUID" "$conffile" && writelog "Copied TMPDIR/IMGUUID ${TMPDIR}/${IMGUUID} to conffile ${conffile}" || \ - ( writelog "Could not copy TMPDIR/IMGUUID -$TMPDIR/$IMGUUID- to conffile ${conffile}!"; cleanexit 1 ) +HWVER=$(grep -i -m1 '^virtualHW.version *= *' "${TMPCONFIG}" | awk -F '=' '{print $2}' | sed -r 's/[^0-9]//g') diff --git a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/set_vmware_include_variables.inc b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/set_vmware_include_variables.inc index 0c45ee59..da820bc6 100644 --- a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/set_vmware_include_variables.inc +++ b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/set_vmware_include_variables.inc @@ -3,8 +3,6 @@ ##################################################################### set_vmware_include_variables() { - [ "$mem" -gt 3800 -a "$(uname -m)" != "x86_64" ] && mem=3800 - # temporary disk space for logs, etc... redodir="/tmp/virt/vmware/${USER}.$$" @@ -14,9 +12,6 @@ set_vmware_include_variables() { # configfile conffile="${confdir}/run-vmware.conf" - # diskfile - diskfile="${vmpath}" - # users vmware config folder [ -z "${HOME}" ] && HOME=$(getent passwd "$(whoami)" | awk -F ':' '{print $6}') vmhome="${HOME}/.vmware" diff --git a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/write_final_vmx.inc b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/write_final_vmx.inc new file mode 100644 index 00000000..f1395369 --- /dev/null +++ b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/includes/write_final_vmx.inc @@ -0,0 +1,211 @@ + +# check for vmdk file marker %VM_DISK_PATH% and put vmdk path in it's place: also VM_DISK_MODE +# and VM_DISK_REDOLOGDIR. +sed -i 's#%VM_DISK_PATH%#'"$VM_DISKFILE_RO"'#g' "${TMPCONFIG}" +sed -i 's#%VM_DISK_MODE%#'"independent-nonpersistent"'#g' "${TMPCONFIG}" +sed -i 's#%VM_DISK_REDOLOGDIR%#'"$redodir"'#g' "${TMPCONFIG}" + +# Ethernet: All we do is entering a generated MAC, as we do not want to interfere +# in the possible case no networking is wanted. +writelog "Guest MAC: $macaddr" +echo 'ethernet0.addressType = "static"' >> "${TMPCONFIG}" +echo 'ethernet0.address = "'"${macaddr}"'"' >> "${TMPCONFIG}" + +# DVD, CDROM +# XXX: For now it's safe to assume ide channel 1 is free, as we support only one HDD, and if it's IDE, it's on channel 0 +cat >> "${TMPCONFIG}" <<-HEREEND +ide1:0.present = "$cdrom0" +ide1:0.autodetect = "TRUE" +ide1:0.fileName = "auto detect" +ide1:0.deviceType = "cdrom-raw" +ide1:1.present = "$cdrom1" +ide1:1.autodetect = "TRUE" +ide1:1.fileName = "auto detect" +ide1:1.deviceType = "cdrom-raw" +HEREEND + +if [ -n "$FLOPPYIMG" ]; then + floppy1="TRUE" +else + floppy1="FALSE" +fi + +# Floppies: +cat >> "${TMPCONFIG}" <<-HEREEND +floppy0.present = "$floppy0" +floppy0.startConnected = "FALSE" +floppy0.autodetect = "TRUE" +floppy0.fileName = "auto detect" +floppy1.present = "$floppy1" +floppy1.startConnected = "TRUE" +floppy1.fileType = "file" +floppy1.fileName = "$FLOPPYIMG" +HEREEND + +writelog "numvcpus = ${cpu_cores} - maxvcpus=${real_core_count}" + +# RAM, CPUs +cat >> "${TMPCONFIG}" <<-HEREEND +numvcpus = "$cpu_cores" +cpuid.coresPerSocket = "$cores_per_socket" +maxvcpus = "$real_core_count" +memsize = "$mem" +MemAllowAutoScaleDown = "FALSE" +MemTrimRate = "-1" +HEREEND + +# USB fallback: Only write usb config if there's none +if ! grep -q -i "^usb\.present" "${TMPCONFIG}"; then + # Nothing found, go ahead + if [ -n "$SLX_EXAM" ]; then + # Exam mode: Default to no USB + sed -i '/^usb\./Id' "${TMPCONFIG}" + echo 'usb.present = "FALSE"' >> "${TMPCONFIG}" + else + cat >> "${TMPCONFIG}" <<-HEREEND + usb.present = "TRUE" + HEREEND + fi +fi +sed -i '/^usb\.generic\.autoconnect/Id' "${TMPCONFIG}" +echo 'usb.generic.autoconnect = "TRUE"' >> "${TMPCONFIG}" +# USB 3.0 support changes quality and has different side effects +# with every minor release of vmware. Always force 2.0 for now. +# TODO: Get it fixed by vmware? +sed -i '/^ehci\.present/Id;/^usb_xhci\.present/Id' "${TMPCONFIG}" +echo 'ehci.present = "TRUE"' >> "${TMPCONFIG}" + +# shared folders +if [ "$HGFS_DISABLED" = "FALSE" ]; then + cat >> "${TMPCONFIG}" <<-HEREEND + sharedFolder.option = "alwaysEnabled" + sharedFolder0.present = "$shfolders" + sharedFolder0.enabled = "$shfolders" + sharedFolder0.expiration = "never" + sharedFolder0.guestName = "$homesharename" + sharedFolder0.hostPath = "$homesharepath" + sharedFolder0.readAccess = "TRUE" + sharedFolder0.writeAccess = "TRUE" + sharedFolder1.present = "$shfolders" + sharedFolder1.enabled = "$shfolders" + sharedFolder1.expiration = "never" + sharedFolder1.guestName = "$commonsharename" + sharedFolder1.hostPath = "$commonsharepath" + sharedFolder1.readAccess = "TRUE" + sharedFolder1.writeAccess = "FALSE" + sharedFolder.maxNum = "2" + hgfs.mapRootShare = "TRUE" + hgfs.linkRootShare = "TRUE" + HEREEND +fi + +# Isolation tools: settings +cat >> "${TMPCONFIG}" <<-HEREEND +isolation.tools.hgfs.disable = "$HGFS_DISABLED" +isolation.tools.dnd.disable = "FALSE" +isolation.tools.copy.enable = "TRUE" +isolation.tools.paste.enabled = "TRUE" +HEREEND + +# Serial port +if [ -n "$serial_0" ]; then + cat >> "${TMPCONFIG}" <<-HEREEND + serial0.present = "TRUE" + serial0.startConnected = "TRUE" + serial0.fileType = "device" + serial0.fileName = "$serial_0" + serial0.tryNoRxLoss = "FALSE" + serial0.autodetect = "FALSE" + HEREEND +fi + +# Parallel port +if [ -n "$parallel_0" ]; then + cat >> "${TMPCONFIG}" <<-HEREEND + parallel0.present = "TRUE" + parallel0.startConnected = "TRUE" + parallel0.fileType = "device" + parallel0.fileName = "$parallel_0" + parallel0.bidirectional = "TRUE" + parallel0.autodetect = "FALSE" + HEREEND +fi + +# Graphics, GPU: 3D will be enabled (even if vmware doesn't support the chip) if we whitelisted it. +if [ -n "$SLX_VMWARE_3D" ]; then + writelog "FORCE3D set - overriding 3D in vmx file." + echo 'mks.gl.allowBlacklistedDrivers = "TRUE"' >> "${TMPCONFIG}" + # We override... play safe and cap the hwVersion to 10, since some i915 chips goofed up with 12 + # Investigate if we might have to do this in other cases where we don't override + if grep -qi '^mks.enable3d.*true' "${TMPCONFIG}"; then + vmw_cap_hw_version "10" + fi +else + writelog "FORCE3D not set - 3D will only work if GPU/driver is whitelisted by vmware." +fi + +# Disable DPI scaling information passing via vmware tools +sed -i '/^gui.applyHostDisplayScaling/Id' "${TMPCONFIG}" +echo 'gui.applyHostDisplayScalingToGuest = "FALSE"' >> "${TMPCONFIG}" + +# Additinal exam mode settings +if [ -n "$SLX_EXAM" ]; then + echo 'gui.restricted = "true"' >> "${TMPCONFIG}" +fi + +# Hack resolution if we know the desired one is not in the default list of vmx_svga +# For now, only do it on the odd ones, as we don't know if this has any side effects +# This seems unnecessary on Win7 but is required on WinXP - need more research for other OSs +case "$RESOLUTION" in + 1600x900|2560x1440|2880x1800|3200x1800) + X=${RESOLUTION%x*} + Y=${RESOLUTION#*x} + BYTES=$(( ( ( X * Y * 4 + 65535 ) / 65536 ) * 65536 )) + [ "$BYTES" -lt 16777216 ] && BYTES=16777216 + cat >> "${TMPCONFIG}" <<-EOF + svga.autodetect = "FALSE" + svga.vramSize = $BYTES + svga.maxWidth = $X + svga.maxHeight = $Y + EOF + ;; +esac + +# Killing duplicate lines (output much nicer than sort -u): +awk '!a[$0]++' "${TMPCONFIG}" > "${TMPCONFIG}.tmp" && mv -f "${TMPCONFIG}.tmp" "${TMPCONFIG}" + +# Apply $maxhardwareversion to final VMX +if [ -n "$HWVER" ] && [ "$HWVER" -gt "$maxhardwareversion" ]; then + writelog "Hardware version capped to $maxhardwareversion (was $HWVER)" + sed -i 's/^virtualHW\.version.*$/virtualHW.version = "'$maxhardwareversion'"/I' "${TMPCONFIG}" + HWVER="$maxhardwareversion" +fi + +# Enable nested virtualization if not specified in remote vmx +if [ -e "/run/hwinfo" ] && ! grep -qi '^vhv\.enable' "${TMPCONFIG}" \ + && grep -qE '^flags\s*:.*\b(ept|npt)\b' "/proc/cpuinfo" \ + && [ "$HWVER" -ge "9" ]; then + . "/run/hwinfo" + [ "${HW_KVM}" = "ENABLED" ] && echo 'vhv.enable = "TRUE"' >> "${TMPCONFIG}" +fi +# TODO: Need a way to check if supported by hardware before enabling! +#grep -qi '^vpmc\.enable' "${TMPCONFIG}" || echo 'vpmc.enable = "TRUE"' >> "${TMPCONFIG}" + +# Disable space check warnings +sed -i '/^mainMem.freeSpaceCheck/Id' "${TMPCONFIG}" +echo 'mainMem.freeSpaceCheck = "FALSE"' >> "${TMPCONFIG}" + +# See if there are any USB devices connected that we want to pass through immediately +get_usb_devices 'usb.autoConnect.deviceXXXXX = "0x%VENDOR%:0x%PRODUCT%"' \ + | sed -r 's/0x0+/0x/g' \ + | awk '{sub(/XXXXX/,NR-1)}1' \ + >> "${TMPCONFIG}" + +# At last_ Let's copy it to $confdir/run-vmware.conf +if cp -p "${TMPCONFIG}" "$conffile"; then + writelog "Copied TMPDIR/IMGUUID ${TMPCONFIG} to conffile ${conffile}" +else + writelog "Could not copy TMPDIR/IMGUUID -${TMPCONFIG}- to conffile ${conffile}!" + cleanexit 1 +fi + diff --git a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/run-virt.include b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/run-virt.include index e25947e0..f66bc9b8 100644 --- a/core/modules/vmware/data/opt/openslx/vmchooser/vmware/run-virt.include +++ b/core/modules/vmware/data/opt/openslx/vmchooser/vmware/run-virt.include @@ -20,7 +20,7 @@ ################################################################################ VMWAREINCLUDEDIR=/opt/openslx/vmchooser/vmware/includes -vmostype=$(rv_clean_string "$vmostype") +VM_OS_TYPE=$(rv_clean_string "$VM_OS_TYPE") # declaration of default variables for vmware source "${VMWAREINCLUDEDIR}/set_vmware_include_variables.inc" && set_vmware_include_variables @@ -33,39 +33,23 @@ vmw_cap_hw_version() { [ "$1" -lt "$maxhardwareversion" ] && maxhardwareversion="$1" } -if [ "$LEGACY" ]; then - # hardware checks - source "${VMWAREINCLUDEDIR}/set_hardware_legacy.inc" && set_hardware_legacy - # write configuration files - # write_config_files calls: - # set_vmhome_preferences_header - # set_vmware_startup_file - source "${VMWAREINCLUDEDIR}/write_config_files_legacy.inc" && write_config_files_legacy -else - # write configuration files - source "${VMWAREINCLUDEDIR}/write_config_files.inc" +# get information from downloaded vmx +source "${VMWAREINCLUDEDIR}/parse_vmx.inc" - # parse the given vmx file - source "${VMWAREINCLUDEDIR}/parse_vmx.inc" -fi +# determine limitations wrt RAM and CPU count of VM +source "${VMWAREINCLUDEDIR}/determine_hardware_limitations.inc" -# logging and stdout -# needs writelog() from vmchooser-run_virt -source "${VMWAREINCLUDEDIR}/logging.inc" && logging +# create file and directory structure for vmware setup +source "${VMWAREINCLUDEDIR}/create_static_directory_structure.inc" -# Apply $maxhardwareversion to final VMX -HWVER=$(grep -i '^virtualHW.version *= *' "$conffile" | head -n 1 | awk -F '=' '{print $2}' | sed -r 's/[^0-9]//g') -if [ -n "$HWVER" ] && [ "$HWVER" -gt "$maxhardwareversion" ]; then - writelog "Hardware version capped to $maxhardwareversion (was $HWVER)" - sed -i 's/^virtualHW\.version.*$/virtualHW.version = "'$maxhardwareversion'"/I' "$conffile" -fi +# create preferences file ${vmhome}/preferences +source "${VMWAREINCLUDEDIR}/create_vmhome_preferences_file.inc" && create_vmhome_preferences_file -# See if there are any USB devices connected that we want to pass through immediately -get_usb_devices 'usb.autoConnect.deviceXXXXX = "0x%VENDOR%:0x%PRODUCT%"' \ - | sed -r 's/0x0+/0x/g' \ - | awk '{sub(/XXXXX/,NR-1)}1' \ - >> "$conffile" +# parse the given vmx file +source "${VMWAREINCLUDEDIR}/write_final_vmx.inc" +# print summary - needs writelog() from vmchooser-run_virt +source "${VMWAREINCLUDEDIR}/log_config_summary.inc" # For debugging cp "$conffile" "/tmp/vmware-last-config" diff --git a/core/modules/vmware/module.build b/core/modules/vmware/module.build index bac61583..f321b084 100644 --- a/core/modules/vmware/module.build +++ b/core/modules/vmware/module.build @@ -1,12 +1,12 @@ fetch_source() { - [ -e "${MODULE_WORK_DIR}/src" -a -d "${MODULE_WORK_DIR}/src" ] && \ + [ -d "${MODULE_WORK_DIR}/src" ] && \ { rm -r "${MODULE_WORK_DIR}/src" || perror "Could not delete old src dir."; } mkdir -p "${MODULE_WORK_DIR}/src" || perror "Could not mkdir src" - cd "${MODULE_WORK_DIR}/src" || perror "cd fail." + cd "${MODULE_WORK_DIR}/src" || perror "cd to '${MODULE_WORK_DIR}/src' failed." # Get directory listing wget -O "index.html" "$REQUIRED_DOWNLOAD_BASE" || perror "Could not download vmware dir index" - + VMWARE_BUNDLE_FILE=$(grep -E -o -i "href=\"VMware-$REQUIRED_TYPE-[^\"]+[\._\-]$ARCHREGEX[\._\-][^\"]+\"" "index.html" | head -n 1 | awk -F '"' '{printf $2}') [ -z "$VMWARE_BUNDLE_FILE" ] && perror "Could not determine vmware $REQUIRED_TYPE bundle file for current arch from $MODULE_WORK_DIR/src/index.html" # Download file @@ -34,11 +34,11 @@ build() { # prepare the build directory with the files needed during the chroot cp "${MODULE_WORK_DIR}/src/$VMWARE_BUNDLE_FILE" "${MODULE_BUILD_DIR}/$VMWARE_BUNDLE_FILE" - cp -r "${MODULE_WORK_DIR}/patches" "${MODULE_BUILD_DIR}" + cp -r "${MODULE_DIR}/patches" "${MODULE_BUILD_DIR}" # sanity check to see if KERNEL_HEADERS_DIR is set and exists [ -z "${KERNEL_HEADERS_DIR}" -o ! -e "${KERNEL_HEADERS_DIR}" ] && perror "KERNEL_HEADERS_DIR ('"${KERNEL_HEADERS_DIR}"') not found. Was the kernel module built?" - + # build in two steps, to be able to use mltk function while patching modules pinfo "Installing vmware per chroot..." chroot_run "${MODULE_BUILD_DIR}" <<-EOF @@ -54,7 +54,7 @@ build() { for KMOD in *.tar; do SHORT="${KMOD%%.tar}" [ -e ".${SHORT}.patched" ] && continue - for PATCH in $(find "${MODULE_WORK_DIR}/patches/" -name "${SHORT}__*__*.patch"); do + for PATCH in $(find "${MODULE_DIR}/patches/" -name "${SHORT}__*__*.patch"); do parse_patch_name "$PATCH" [ -z "${MIN_KERN}" -o -z "${MAX_KERN}" ] && perror "Could not parse patch filename" if version_lt "$TARGET_KERNEL_SHORT" "$MIN_KERN" || version_gt "$TARGET_KERNEL_SHORT" "$MAX_KERN"; then @@ -101,7 +101,7 @@ build() { # This file was formerly stored in data/opt/openslx/vmchooser/vmware/vmware.conf. mkdir -p "${MODULE_BUILD_DIR}/opt/openslx/vmchooser/vmware/" || perror "could not mkdir "${MODULE_BUILD_DIR}/opt/openslx/vmchooser/vmware/"." - + cat > "${MODULE_BUILD_DIR}/opt/openslx/vmchooser/vmware/vmware.conf" <<-EOF # configuration file written by vmware/module.build vmnet0=true @@ -127,7 +127,7 @@ post_copy() { tarcopy "$(find /usr/lib/ /usr/lib64 -name gconv -type d)" "$TARGET_BUILD_DIR" # Update Icon cache for vmplayer - gtk-update-icon-cache-3.0 "${TARGET_BUILD_DIR}/usr/share/icons/hicolor/" || pwarning "update-icon-cache-3.0 failed." + gtk-update-icon-cache-3.0 "${TARGET_BUILD_DIR}/usr/share/icons/hicolor/" || pwarning "update-icon-cache-3.0 failed." # fix vmware-usbarbitrator bug date +'%Y.%m.%d' >"${TARGET_BUILD_DIR}/etc/arch-release" diff --git a/core/modules/vmware/module.conf b/core/modules/vmware/module.conf index 697ba546..02770c34 100644 --- a/core/modules/vmware/module.conf +++ b/core/modules/vmware/module.conf @@ -1,4 +1,4 @@ -REQUIRED_DOWNLOAD_BASE="http://softwareupdate.vmware.com/cds/vmw-desktop/ws/12.1.0/3272444/linux/core/" +REQUIRED_DOWNLOAD_BASE="http://softwareupdate.vmware.com/cds/vmw-desktop/ws/12.5.2/4638234/linux/core/" REQUIRED_TYPE="workstation" REQUIRED_MODULES="kernel" REQUIRED_DIRECTORIES=" @@ -38,8 +38,8 @@ REQUIRED_VMWARE_DELETIONS=" /etc/cups/thnuclnt.convs /etc/cups/thnuclnt.types /etc/modprobe.d/vmware-fuse.conf - /lib/modules/3.11.0-13-generic/misc/vmnet.ko - /lib/modules/3.11.0-13-generic/misc/vmmon.ko + /lib/modules/*-generic/misc/vmnet.ko + /lib/modules/*-generic/misc/vmmon.ko /usr/share/mime/packages/vmware-player.xml /usr/share/applications/vmware* /usr/share/desktop-directories/vmware-ace-vms.directory diff --git a/core/modules/vmware/patches/vmmon__4.9__12.0.0-12.5.2.patch b/core/modules/vmware/patches/vmmon__4.9__12.0.0-12.5.2.patch new file mode 100644 index 00000000..054dd8a1 --- /dev/null +++ b/core/modules/vmware/patches/vmmon__4.9__12.0.0-12.5.2.patch @@ -0,0 +1,13 @@ +--- a/linux/hostif.c 2016-12-22 14:27:00.425933040 +0100 ++++ b/linux/hostif.c 2016-12-22 14:27:38.746706220 +0100 +@@ -1162,7 +1162,9 @@ + int retval; + + down_read(¤t->mm->mmap_sem); +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) ++ retval = get_user_pages((unsigned long)uvAddr, numPages, 0, ppages, NULL); ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + retval = get_user_pages((unsigned long)uvAddr, numPages, 0, 0, ppages, NULL); + #else + retval = get_user_pages(current, current->mm, (unsigned long)uvAddr, diff --git a/core/modules/vmware/patches/vmnet__4.9__12.0.0-12.5.2.patch b/core/modules/vmware/patches/vmnet__4.9__12.0.0-12.5.2.patch new file mode 100644 index 00000000..18ef062b --- /dev/null +++ b/core/modules/vmware/patches/vmnet__4.9__12.0.0-12.5.2.patch @@ -0,0 +1,13 @@ +--- a/userif.c 2016-12-22 14:29:43.237218623 +0100 ++++ b/userif.c 2016-12-22 14:31:03.258834075 +0100 +@@ -113,7 +113,9 @@ + int retval; + + down_read(¤t->mm->mmap_sem); +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) ++ retval = get_user_pages(addr, 1, 0, &page, NULL); ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + retval = get_user_pages(addr, 1, 1, 0, &page, NULL); + #else + retval = get_user_pages(current, current->mm, addr, diff --git a/core/modules/xorg/module.build b/core/modules/xorg/module.build index 16e0bb5b..8806fc9f 100644 --- a/core/modules/xorg/module.build +++ b/core/modules/xorg/module.build @@ -12,11 +12,19 @@ build() { tarcopy "$(cat "$COPYLIST" | sort -u)" "${MODULE_BUILD_DIR}" # copy udev rules to correct location - [ -d "${MODULE_BUILD_DIR}/lib/udev" ] && mv "${MODULE_BUILD_DIR}/lib/udev" "${MODULE_BUILD_DIR}/usr/lib/" + if [ -d "${MODULE_BUILD_DIR}/lib/udev" ]; then + cp -r "${MODULE_BUILD_DIR}/lib/udev" "${MODULE_BUILD_DIR}/usr/lib/" + fi + if [ -d "${MODULE_BUILD_DIR}/etc/udev" ]; then + cp -r "${MODULE_BUILD_DIR}/etc/udev" "${MODULE_BUILD_DIR}/usr/lib/" + fi + rm -rf -- "${MODULE_BUILD_DIR}/lib/udev" "${MODULE_BUILD_DIR}/etc/udev" + # This freezed/crashed X with certain gfx cards (radeon R240) + rm -f -- "${MODULE_BUILD_DIR}/usr/lib/xorg/modules/libglamoregl.so" } post_copy() { mkdir -p "${TARGET_BUILD_DIR}/etc/X11" - [ ! -e ${TARGET_BUILD_DIR}/etc/X11/X ] && ln -s /usr/bin/Xorg ${TARGET_BUILD_DIR}/etc/X11/X + [ ! -e ${TARGET_BUILD_DIR}/etc/X11/X ] && ln -s /usr/bin/Xorg ${TARGET_BUILD_DIR}/etc/X11/X } diff --git a/core/modules/xorg/module.conf b/core/modules/xorg/module.conf index b99f0e2a..6aacc654 100644 --- a/core/modules/xorg/module.conf +++ b/core/modules/xorg/module.conf @@ -10,10 +10,18 @@ REQUIRED_BINARIES=" xkbbell xkbevd xrandr + xset + xdotool xkbcomp vmmouse_detect " REQUIRED_DIRECTORIES=" /usr/share/X11 + /usr/share/fonts + /etc/fonts + /usr/bin + /bin + /usr/lib/udev +" +REQUIRED_FILES=" " -REQUIRED_FILES="" diff --git a/core/modules/xorg/module.conf.debian b/core/modules/xorg/module.conf.debian index 86d473a3..3bde05ef 100644 --- a/core/modules/xorg/module.conf.debian +++ b/core/modules/xorg/module.conf.debian @@ -1,4 +1,5 @@ REQUIRED_INSTALLED_PACKAGES=" + ttf-dejavu " REQUIRED_CONTENT_PACKAGES=" xserver-xorg @@ -33,8 +34,9 @@ REQUIRED_CONTENT_PACKAGES=" @xserver-xorg-video-geode @xserver-xorg-video-s3 @xserver-xorg-video-tdfx + ttf-dejavu " REQUIRED_DIRECTORIES+=" - /usr/lib + /usr/lib " REQUIRED_FILES="" diff --git a/core/modules/xorg/module.conf.ubuntu b/core/modules/xorg/module.conf.ubuntu index 41a8739a..4f063440 100644 --- a/core/modules/xorg/module.conf.ubuntu +++ b/core/modules/xorg/module.conf.ubuntu @@ -1,6 +1,7 @@ REQUIRED_INSTALLED_PACKAGES=" -" -REQUIRED_CONTENT_PACKAGES=" + fonts-dejavu-core + fonts-dejavu-extra + ttf-dejavu-core xserver-xorg$UBUNTU_XORG_PKG_SUFFIX xserver-xorg-core$UBUNTU_XORG_PKG_SUFFIX libgl1-mesa-dri$UBUNTU_XORG_PKG_SUFFIX @@ -8,18 +9,47 @@ REQUIRED_CONTENT_PACKAGES=" xkb-data x11-xkb-utils x11-xserver-utils + xdotool xserver-xorg-input-evdev$UBUNTU_XORG_PKG_SUFFIX - xserver-xorg-input-mouse$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-input-synaptics$UBUNTU_XORG_PKG_SUFFIX xserver-xorg-input-vmmouse$UBUNTU_XORG_PKG_SUFFIX - xserver-xorg-video-intel$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-input-wacom$UBUNTU_XORG_PKG_SUFFIX xserver-xorg-video-ati$UBUNTU_XORG_PKG_SUFFIX - xserver-xorg-video-vesa$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-fbdev$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-intel$UBUNTU_XORG_PKG_SUFFIX xserver-xorg-video-mga$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-nouveau$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-radeon$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-sisusb$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-vesa$UBUNTU_XORG_PKG_SUFFIX xserver-xorg-video-vmware$UBUNTU_XORG_PKG_SUFFIX +" +REQUIRED_CONTENT_PACKAGES=" + fonts-dejavu-core + fonts-dejavu-extra + ttf-dejavu-core + xserver-xorg$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-core$UBUNTU_XORG_PKG_SUFFIX + libgl1-mesa-dri$UBUNTU_XORG_PKG_SUFFIX + libgl1-mesa-glx$UBUNTU_XORG_PKG_SUFFIX + xkb-data + x11-xkb-utils + x11-xserver-utils + xdotool + xserver-xorg-input-evdev$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-input-synaptics$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-input-vmmouse$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-input-wacom$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-ati$UBUNTU_XORG_PKG_SUFFIX xserver-xorg-video-fbdev$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-intel$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-mga$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-nouveau$UBUNTU_XORG_PKG_SUFFIX xserver-xorg-video-radeon$UBUNTU_XORG_PKG_SUFFIX xserver-xorg-video-sisusb$UBUNTU_XORG_PKG_SUFFIX - xserver-xorg-video-nouveau$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-vesa$UBUNTU_XORG_PKG_SUFFIX + xserver-xorg-video-vmware$UBUNTU_XORG_PKG_SUFFIX + @xserver-xorg-input-mouse$UBUNTU_XORG_PKG_SUFFIX @xserver-xorg-video-openchrome$UBUNTU_XORG_PKG_SUFFIX @xserver-xorg-video-savage$UBUNTU_XORG_PKG_SUFFIX @xserver-xorg-video-trident$UBUNTU_XORG_PKG_SUFFIX diff --git a/core/modules/xscreensaver/data/etc/X11/Xsession.d/95-xscreensaver b/core/modules/xscreensaver/data/etc/X11/Xsession.d/95-xscreensaver new file mode 100755 index 00000000..fc6588ae --- /dev/null +++ b/core/modules/xscreensaver/data/etc/X11/Xsession.d/95-xscreensaver @@ -0,0 +1,33 @@ +#!/bin/ash + +if which xscreensaver; then + [ -z "$UID" ] && UID=$(id -u) + [ -z "$HOME" ] && HOME="$(getent passwd "$UID" | head -n 1 | awk -F ':' '{print $6}')" + if ! [ -s "$HOME/.xscreensaver" ]; then + . /opt/openslx/config + NUM=${SLX_SCREEN_STANDBY_TIMEOUT} + if [ -n "$NUM" ] && [ "$NUM" -gt 60 ]; then + SECS=0$(( NUM % 60 )) + MINS=0$(( ( NUM / 60 ) % 60 )) + HRS=0$(( ( NUM / 3600 ) % 60 )) + STANDBY="${HRS:$(( ${#HRS} - 2 )):2}:${MINS:$(( ${#MINS} - 2 )):2}:${SECS:$(( ${#SECS} - 2 )):2}" + else + STANDBY=0:00:00 + fi + cat > "$HOME/.xscreensaver" <<EOF +mode: blank +timeout: 24:00:00 +lock: True +lockTimeout: 0:00:10 +fade: False +unfade: False +dpmsEnabled: True +dpmsStandby: $STANDBY +dpmsSuspend: $STANDBY +dpmsOff: $STANDBY +EOF + fi + xscreensaver -no-splash & +fi +true + diff --git a/core/modules/xscreensaver/module.build b/core/modules/xscreensaver/module.build new file mode 100644 index 00000000..435a7b10 --- /dev/null +++ b/core/modules/xscreensaver/module.build @@ -0,0 +1,13 @@ +fetch_source() { + : +} + +build() { + COPYLIST="list_dpkg_output" + list_packet_files > "$COPYLIST" + tarcopy "$(cat "${COPYLIST}" | sort -u)" "${MODULE_BUILD_DIR}" +} + +post_copy() { + : +} diff --git a/core/modules/xscreensaver/module.conf b/core/modules/xscreensaver/module.conf new file mode 100644 index 00000000..2134f0cb --- /dev/null +++ b/core/modules/xscreensaver/module.conf @@ -0,0 +1,8 @@ +REQUIRED_BINARIES=" + xscreensaver + xscreensaver-command +" +REQUIRED_LIBRARIES="" +REQUIRED_DIRECTORIES=" + /etc/pam.d/ +" diff --git a/core/modules/xscreensaver/module.conf.ubuntu b/core/modules/xscreensaver/module.conf.ubuntu new file mode 100644 index 00000000..b25b886f --- /dev/null +++ b/core/modules/xscreensaver/module.conf.ubuntu @@ -0,0 +1,6 @@ +REQUIRED_CONTENT_PACKAGES=" + xscreensaver +" +REQUIRED_INSTALLED_PACKAGES=" + xscreensaver +" diff --git a/core/rootfs/rootfs-stage31/data/inc/activate_sysconfig b/core/rootfs/rootfs-stage31/data/inc/activate_sysconfig index c9b74791..ec98ff70 100644 --- a/core/rootfs/rootfs-stage31/data/inc/activate_sysconfig +++ b/core/rootfs/rootfs-stage31/data/inc/activate_sysconfig @@ -66,10 +66,15 @@ HEREEND cd "${TEMP_EXTRACT_DIR}" # first we look for local config.tgz files, which we merge with the common # config.tgz files - local LOCAL_CONFIG_DIR="openslx-configs/${SLX_LOCAL_CONFIG}" - if [ -n "${SLX_LOCAL_CONFIG}" -a -d "${LOCAL_CONFIG_DIR}" ]; then - tarcopy "${LOCAL_CONFIG_DIR}" "${TEMP_EXTRACT_DIR}" - echo "Merged local configuration files for '${SLX_LOCAL_CONFIG}'" + if [ -n "${SLX_LOCAL_CONFIG}" ]; then + local MOD + for MOD in ${SLX_LOCAL_CONFIG}; do + local LOCAL_CONFIG_DIR="openslx-configs/${MOD}" + if [ -d "${LOCAL_CONFIG_DIR}" ]; then + tarcopy "${LOCAL_CONFIG_DIR}" "${TEMP_EXTRACT_DIR}" + echo "Merged local configuration files for '${MOD}'" + fi + done fi # purge openslx-configs/* rm -rf -- "openslx-configs/" @@ -91,6 +96,17 @@ HEREEND # fetch_sysconfig || drop_shell "Could not download remote config" +if ! ash -n "${CONFIG}-remote"; then + echo -e "\n\tFATAL: Could not download configuration!" + echo -e "\tAborting boot since the system would be in an unusable state." + echo -en "\tRebooting in 60 seconds" + timeout=60 + while [ $(( timeout-- )) -gt 0 ]; do + echo -n "." + sleep 1 + done + echo b > /proc/sysrq-trigger +fi . "${CONFIG}-remote" || drop_shell "Could not source remote config" fetch_config_files || drop_shell "Could not download config.tgz" update_sysconfig || drop_shell "Could not update sysconfig" diff --git a/core/rootfs/rootfs-stage31/data/inc/setup_network b/core/rootfs/rootfs-stage31/data/inc/setup_network index 13c52289..956df03c 100644 --- a/core/rootfs/rootfs-stage31/data/inc/setup_network +++ b/core/rootfs/rootfs-stage31/data/inc/setup_network @@ -26,14 +26,21 @@ mkdir -p "${FUTURE_ROOT}/etc/udev/rules.d" IP_OUT=$(ip a | grep -B 1 "/ether" | sed -r '/^--$/d;$!N;s#^[0-9]+: ([a-z0-9\.:]+): .*?/ether ([0-9a-fA-Z:]+) .*$#\1==\2#') if ! echo "$IP_OUT" | grep -q -- "$MAC"; then - drop_shell "Boot interface not found in interface list. NIC driver missing?" + drop_shell "--- +$(ip a) +--- +$IP_OUT +--- + +Boot interface $MAC not found in interface list. NIC driver missing?" + : fi for LINE in $IP_OUT; do IFACE=$(echo "$LINE" | awk -F '==' '{printf $1}') IFMAC=$(echo "$LINE" | awk -F '==' '{printf $2}' | tr '[A-Z]' '[a-z]') # udev requires mac addesses to be lowercase (a-f), see http://www.debianhelp.co.uk/udev.htm echo "${IFACE} = ${IFMAC}" - + if [ "x$IFMAC" == "x$MAC" ]; then brctl addbr "$BRIDGE" || drop_shell "Could not create bridge $BRIDGE" brctl stp "$BRIDGE" 0 diff --git a/core/rootfs/rootfs-stage31/data/inc/setup_stage32 b/core/rootfs/rootfs-stage31/data/inc/setup_stage32 index 5ec5a69d..070583aa 100644 --- a/core/rootfs/rootfs-stage31/data/inc/setup_stage32 +++ b/core/rootfs/rootfs-stage31/data/inc/setup_stage32 @@ -58,11 +58,9 @@ if [ $SPLASH -eq 1 ]; then fi fi -# Kinda specific for virtualization environment: Autologin and run VM for benchmarks -if [ -n "$SLX_BENCHMARK_VM" ]; then +# Auto login to demo user requested? +if [ -n "$SLX_AUTOLOGIN" ]; then # Enable KDM autologin for demo user sed -i 's/^AutoLoginUser=.*//;s/^AutoLoginEnable=.*/AutoLoginEnable=true\nAutoLoginUser=demo/' "${FUTURE_ROOT}/etc/kde4/kdm/kdmrc" - # Running the VM automatically has to be taken care of by run-virt and vmchooser. SLX_BENCHMARK_VM should contain - # a numeric value for the index in vmchooser fi diff --git a/core/rootfs/rootfs-stage31/data/init b/core/rootfs/rootfs-stage31/data/init index 5e6d1caf..4b3a800b 100755 --- a/core/rootfs/rootfs-stage31/data/init +++ b/core/rootfs/rootfs-stage31/data/init @@ -118,6 +118,10 @@ for mnt in proc sys run ; do done # HACK HACK: Klausurmodus +if [ "x$SLX_PVS_DEDICATED" = "xyes" ] || [ "x$SLX_PVS_HYBRID" = "xyes" ]; then + sed -i '/^SLX_EXAM=/d' "${FUTURE_ROOT}/opt/openslx/config" + SLX_EXAM= +fi # Putting this here as we're hopefully moving to the all new dracut solution soon # so there's no reason to make it pretty now if [ -n "$SLX_EXAM" ]; then diff --git a/core/rootfs/rootfs-stage31/module.build b/core/rootfs/rootfs-stage31/module.build index cda5788a..7706f6fa 100644 --- a/core/rootfs/rootfs-stage31/module.build +++ b/core/rootfs/rootfs-stage31/module.build @@ -5,10 +5,10 @@ fetch_source() { build() { local COPYLIST BIN_LOCATION DRM_MODULES FILE BIN MODNAME PCI_FILE ALIAS VENDOR DEVICE LIB - COPYLIST="list_binaries_and_files" + local COPYLIST="list_binaries_and_files" [ -e "$COPYLIST" ] && rm -f "$COPYLIST" for BIN in $REQUIRED_BINARIES; do - BIN_LOCATION=$(which "$BIN") + local BIN_LOCATION=$(which "$BIN") [ -z "$BIN_LOCATION" ] && perror "Cannot find $BIN" get_link_chain "$BIN_LOCATION" >> "$COPYLIST" done @@ -20,13 +20,13 @@ build() { # generate drm module loading database pinfo "Generating PCI ID database for DRM drivers" - DRM_MODULES="$KERNEL_BASE_DIR/lib/modules/$TARGET_KERNEL_LONG/kernel/drivers/gpu/drm" - PCI_FILE="$MODULE_BUILD_DIR/drm.cfg" + local DRM_MODULES="$KERNEL_BASE_DIR/lib/modules/$TARGET_KERNEL_LONG/kernel/drivers/gpu/drm" + local PCI_FILE="$MODULE_BUILD_DIR/drm.cfg" [ -d "$DRM_MODULES" ] || perror "DRM dir not found at $DRM_MODULES" cp "$MODULE_DIR/templates/drm.cfg" "$PCI_FILE" || perror "Could not copy drm.cfg from templates dir" echo "# -- generated from kernel $TARGET_KERNEL_LONG modules:" >> "$PCI_FILE" for FILE in $(find "$DRM_MODULES" -name "*.ko"); do - MODNAME=$(basename "$FILE") + local MODNAME=$(basename "$FILE") MODNAME=${MODNAME%.ko} [ -z "$MODNAME" ] && perror "$FILE equals empty modname" echo "# $MODNAME" >> "$PCI_FILE" diff --git a/core/rootfs/rootfs-stage32/data/etc/systemd/system/update-etc_issue.service b/core/rootfs/rootfs-stage32/data/etc/systemd/system/update-etc_issue.service index 21a09b7c..bdfab085 100644 --- a/core/rootfs/rootfs-stage32/data/etc/systemd/system/update-etc_issue.service +++ b/core/rootfs/rootfs-stage32/data/etc/systemd/system/update-etc_issue.service @@ -1,5 +1,6 @@ [Unit] Description=Update /etc/issue +After=setup-partitions.service Before=getty.target shutdown.target DefaultDependencies=no diff --git a/core/rootfs/rootfs-stage32/data/opt/openslx/bin/slxlog b/core/rootfs/rootfs-stage32/data/opt/openslx/bin/slxlog index 52320c1a..09cb9b79 100755 --- a/core/rootfs/rootfs-stage32/data/opt/openslx/bin/slxlog +++ b/core/rootfs/rootfs-stage32/data/opt/openslx/bin/slxlog @@ -13,13 +13,29 @@ export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/o . /opt/openslx/config [ -z "$SLX_REMOTE_LOG" ] && exit 3 -LOGCHECK="/tmp/remote_log_check" +USER=$(whoami) +LOGCHECK="/tmp/remote_log_check-$USER" NOW=$(date +%s) +DELFILE= +SYNC= -if [ "x$1" = "x-e" -o "x$1" = "x--echo" ]; then +while [ $# -gt 0 ]; do + case "$1" in + -e|--echo) + echo "$@" + ;; + -d|--delete) + DELFILE=yes + ;; + -s|--sync) + SYNC=yes + ;; + *) + break + ;; + esac shift - echo "$@" -fi +done [ $# -eq 0 ] && exit 0 @@ -42,14 +58,13 @@ if [ -r "$LOGCHECK" ]; then fi fi echo "$NOW $TYPE" >> "$LOGCHECK" -chmod 0666 "$LOGCHECK" 2>/dev/null +chmod 0600 "$LOGCHECK" 2>/dev/null if [ $# -lt 2 ]; then MSG="Missing text for $@" else MSG="$2" fi -USER=$(whoami) MSG="[$USER] $MSG" if [ $# -gt 2 ]; then @@ -62,15 +77,28 @@ else CURLLOG="/dev/null" fi -if [ -n "$EXTRA" ] && [ -r "$EXTRA" -a -s "$EXTRA" ] && [ "$(stat -c %s "$EXTRA")" -lt "10000" ]; then # valid file attachment - curl --data-urlencode "type=$TYPE" --data-urlencode "description=$MSG" --data-urlencode "longdesc@$EXTRA" "$SLX_REMOTE_LOG" >> "$CURLLOG" 2>&1 & -elif [ -z "$EXTRA" ]; then # no attachment - curl --data-urlencode "type=$TYPE" --data-urlencode "description=$MSG" "$SLX_REMOTE_LOG" >> "$CURLLOG" 2>&1 & -elif [ -s "$EXTRA" ]; then # empty attachment file (or missing) - curl --data-urlencode "type=$TYPE" --data-urlencode "description=$MSG" --data-urlencode "longdesc=Attachment too large: $EXTRA" "$SLX_REMOTE_LOG" >> "$CURLLOG" 2>&1 & -else # attachment file to big (more than 10k) - curl --data-urlencode "type=$TYPE" --data-urlencode "description=$MSG" --data-urlencode "longdesc=Attachment missing/empty: $EXTRA" "$SLX_REMOTE_LOG" >> "$CURLLOG" 2>&1 & +UUID= +if [ -s /run/system-uuid ]; then + UUID=$(cat /run/system-uuid) +fi + +submitlog () { + if [ -n "$EXTRA" ] && [ -r "$EXTRA" -a -s "$EXTRA" ] && [ "$(stat -c %s "$EXTRA")" -lt "10000" ]; then # valid file attachment + curl --data-urlencode "uuid=$UUID" --data-urlencode "type=$TYPE" --data-urlencode "description=$MSG" --data-urlencode "longdesc@$EXTRA" "$SLX_REMOTE_LOG" >> "$CURLLOG" 2>&1 + elif [ -z "$EXTRA" ]; then # no attachment + curl --data-urlencode "uuid=$UUID" --data-urlencode "type=$TYPE" --data-urlencode "description=$MSG" "$SLX_REMOTE_LOG" >> "$CURLLOG" 2>&1 + elif [ -s "$EXTRA" ]; then # attachment file to big (more than 10k) + curl --data-urlencode "uuid=$UUID" --data-urlencode "type=$TYPE" --data-urlencode "description=$MSG" --data-urlencode "longdesc=Attachment too large: $EXTRA" "$SLX_REMOTE_LOG" >> "$CURLLOG" 2>&1 + else # empty attachment file (or missing) + curl --data-urlencode "uuid=$UUID" --data-urlencode "type=$TYPE" --data-urlencode "description=$MSG" --data-urlencode "longdesc=Attachment missing/empty: $EXTRA" "$SLX_REMOTE_LOG" >> "$CURLLOG" 2>&1 + fi + [ -n "$DELFILE" ] && [ -n "$EXTRA" ] && rm -f -- "$EXTRA" +} + +if [ -z "$SYNC" ]; then + submitlog & + exit 0 fi -exit 0 +submitlog diff --git a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/openslx-create_issue b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/openslx-create_issue index 879463cd..c70e0356 100755 --- a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/openslx-create_issue +++ b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/openslx-create_issue @@ -1,4 +1,5 @@ #!/bin/bash +# Needs bash for string manipulation # Copyright (c) 2013, 2014 - bwLehrpool Projekt # Copyright (c) 2012 - OpenSLX GmbH # @@ -12,14 +13,75 @@ # # First script for initial ramfs for OpenSLX linux stateless clients ############################################################################# -PATH=$PATH:/opt/openslx/bin:/opt/openslx/sbin # Set greeting and add information about the booted system -len=$(expr length "$(cat /etc/hostname)") -while [ $len -le 56 ] ; do - space="$space " - len=$(($len + 1)) -done -sed "s/%space%/$space/g" /opt/openslx/etc/issue.template > /etc/issue +declare -rg INFILE=/opt/openslx/etc/issue.template +declare -rg TMPFILE=$(mktemp) +declare -rg OUTFILE=/etc/issue + +. /opt/openslx/config + +# Replace known variables and determine maximum line length +MAX=0 +while IFS='' read -r line || [ -n "$line" ]; do + line="${line//"%ip%"/"$SLX_PXE_CLIENT_IP"}" + line="${line//"%hostname%"/"$SLX_HOSTNAME"}" + tst="${line//"%space%"/}" + len=${#tst} + [ "$len" -gt "$MAX" ] && MAX=$len + echo "$line" +done < "$INFILE" > "$TMPFILE" +player=$(< /etc/vmware/config grep -m1 '^product.version' | awk -F= '{print $2}') +kernel=$(uname -r) +system="$(dmidecode -s system-manufacturer | grep -vP "unknown|filled|^#") $(dmidecode -s system-product-name | grep -vP "unknown|filled|^#")" +linkspeed=$(cat /sys/class/net/eth0/speed) +tmpstatus=$(grep -m1 ' /tmp ' /proc/mounts | awk '{print $3}') +if [ -z "$tmpstatus" ] || [ "$tmpstatus" = "tmpfs" ]; then + tmpstatus="RAMDISK" +else + tmpstatus="HDD" +fi +tmpstatus="$(df -P | grep -m1 ' /tmp$' | awk '{printf "%.1f", $2 / 1024 / 1024}')GiB ($tmpstatus)" + +cat >> "$TMPFILE" <<EOF +System model: %space% $system +Kernel version: %space% $kernel +Temporary directory: %space% $tmpstatus +Boot server: %space% $SLX_PXE_SERVER_IP +EOF +if [ -n "$linkspeed" ]; then + echo "Link speed: %space% ${linkspeed}MBit" >> "$TMPFILE" +fi +if [ -n "$SLX_SHUTDOWN_SCHEDULE" ]; then + echo "Scheduled shutdown: %space% $SLX_SHUTDOWN_SCHEDULE" >> "$TMPFILE" +fi +if [ -n "$SLX_REBOOT_SCHEDULE" ]; then + echo "Scheduled reboot: %space% $SLX_REBOOT_SCHEDULE" >> "$TMPFILE" +fi +if [ -n "$player" ]; then + echo "VMware version: %space% ${player//'"'/}" >> "$TMPFILE" +fi + +echo "" >> "$TMPFILE" + +# Fix up spacing for right-aligned text +while IFS='' read -r line || [ -n "$line" ]; do + tst=${line/"%space%"/} + if [ "$(( ${#line} - ${#tst} ))" -eq 7 ]; then + space= + while true; do + tst=${line/"%space%"/"$space"} + if [ "${#tst}" -ge "$MAX" ]; then + line="$tst" + break + fi + space=" $space" + done + fi + echo "$line" +done < "$TMPFILE" > "$OUTFILE" + +rm -f -- "$TMPFILE" + diff --git a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-load_gfx_driver b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-load_gfx_driver index 7bc310fc..e6fd32cf 100755 --- a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-load_gfx_driver +++ b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-load_gfx_driver @@ -1,5 +1,5 @@ #!/bin/bash -PATH=$PATH:/opt/openslx/bin:/opt/openslx/sbin + PCIFILE=/tmp/lspci-output if ! lspci -n > "$PCIFILE"; then @@ -7,15 +7,14 @@ if ! lspci -n > "$PCIFILE"; then exit 1 fi -if grep -E ' (8086:0152|8086:0412|8086:0416|1002:6779)( |$)' "$PCIFILE" > /dev/null; then - echo "i915 - enable 3D" - echo -e "# Written by load-gfx-driver\nSLX_VMWARE_3D=yes" >> "/opt/openslx/config" -fi - if lsmod | grep -q '^nvidia\s'; then # nvidia kernel module was loaded in stage31 - download libs + echo "Proprietary nvidia kernel drivers loaded - fetch user space libs" systemctl start setup-slx-addon@nvidia_libs & echo -e "# Written by load-gfx-driver\nSLX_VMWARE_3D=yes" >> "/opt/openslx/config" +elif grep -q -E ' (8086:0102|8086:0152|8086:0162|8086:0412|8086:0416|1002:6779)( |$)' "$PCIFILE"; then + echo "i915 - enable 3D" + echo -e "# Written by load-gfx-driver\nSLX_VMWARE_3D=yes" >> "/opt/openslx/config" fi exit 0 diff --git a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-mount_stage4 b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-mount_stage4 index 10cfca5f..201e7a26 100755 --- a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-mount_stage4 +++ b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-mount_stage4 @@ -2,7 +2,6 @@ # Needs full bash . /opt/openslx/config -PATH=$PATH:/opt/openslx/bin:/opt/openslx/sbin [ -z "${SLX_STAGE4}" ] && { echo "SLX_STAGE4 is not set in /opt/openslx/config." && exit 1; } diff --git a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-setup_partitions b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-setup_partitions index 0c352241..6a353b8f 100755 --- a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-setup_partitions +++ b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-setup_partitions @@ -15,53 +15,61 @@ ############################################################################# # Mount point for persistent scratch partition (type 45) -PERSISTENT="/opt/openslx/persistent" +MOUNT_POINT_45="/opt/openslx/persistent" +PARTITION_FILE="/run/openslx/partitions" +readonly MOUNT_POINT_45 PARTITION_FILE +mkdir -p "/run/openslx" # General formatter for the /tmp partition on a local harddisk -diskfm () { - mopt="" # Global var! +format_disk () { + MOUNT_OPTIONS_SET_BY_FORMAT_DISK="" # Global var! local target="$1" local fslist="xfs jfs ext3 ext2 ext4" local fs local path [ $# -ge 2 ] && fslist="$2" for fs in $fslist ; do - unset available - case $(cat /proc/filesystems) in - *${fs}*) available=yes;; - *) modprobe "${fs}" && available=yes;; - esac - if [ -n "${available}" ]; then - unset found - if which "mkfs.$fs" ; then - found=yes - case "mkfs.$fs" in - mkfs.xfs) - fopt="-f -b size=4k -s size=4k -l size=512b" # fastest formatting possible :) - mopt="-o noexec" - ;; - mkfs.ext2) - fopt="-Fq" - mopt="-o nocheck,noexec" - ;; - mkfs.ext3|mkfs.ext4) - fopt="-Fq" - mopt="-o noexec" - ;; - mkfs.reiserfs) - fopt="-f" - mopt="-o noexec" - ;; - mkfs.jfs) - fopt="-q" - mopt="-o noexec" - ;; - esac - mkfs.$fs ${fopt} "${target}" - fi - [ -n "$found" ] && break + if grep -q "\\b${fs}\\b" "/proc/filesystems"; then + # Filesystem already supported by running kernel + : + elif modprobe "${fs}"; then + # Filesystem module could be loaded and should be supported now + : + else + # Not supported, try next one + continue + fi + if which "mkfs.$fs" ; then + case "$fs" in + xfs) + fopt="-f -b size=4k -s size=4k -l size=512b" # fastest formatting possible :) + MOUNT_OPTIONS_SET_BY_FORMAT_DISK="-o noexec" + ;; + ext2) + fopt="-Fq" + MOUNT_OPTIONS_SET_BY_FORMAT_DISK="-o nocheck,noexec" + ;; + ext3|ext4) + fopt="-Fq" + MOUNT_OPTIONS_SET_BY_FORMAT_DISK="-o noexec" + ;; + reiserfs) + fopt="-f" + MOUNT_OPTIONS_SET_BY_FORMAT_DISK="-o noexec" + ;; + jfs) + fopt="-q" + MOUNT_OPTIONS_SET_BY_FORMAT_DISK="-o noexec" + ;; + *) + fopt= + MOUNT_OPTIONS_SET_BY_FORMAT_DISK= + ;; + esac + mkfs.$fs ${fopt} "${target}" && return 0 # Success! fi done + return 1 } mount_temp () { @@ -89,33 +97,46 @@ mount_temp_fallback () { return 0 } -fdisk -l | sed -n "/^\/dev\//p" > "/etc/disk.partition" +fdisk -l | grep '^/dev/' > "$PARTITION_FILE" -if [ ! -s "/etc/disk.partition" ]; then +if [ ! -s "$PARTITION_FILE" ]; then + udevadm trigger sleep 3 - fdisk -l | sed -n "/^\/dev\//p" > "/etc/disk.partition" + udevadm settle + fdisk -l | grep '^/dev/' > "$PARTITION_FILE" fi echo "Partitions:" -cat "/etc/disk.partition" +cat "$PARTITION_FILE" + +# Get all partitions with given id (list of /dev/sdXX) +get_all_with_id () { + [ -z "$1" ] && return + local ID=$1 + awk '{if (($2 == "*" && $6 == "'$ID'") || ($2 != "*" && $5 == "'$ID'")) print $1}' "$PARTITION_FILE" # watch out for non-spaced '$ID' +} # Check for standard swap partitions and make them available to the system HAVE_SWAP=no -for hdpartnr in $(sed -n -e "/ 82 /p" "/etc/disk.partition" | sed -e "s/[[:space:]].*//"); do - echo -e "$hdpartnr\tswap\t\tswap\t\tdefaults\t 0 0" >> "/etc/fstab" - swapon "$hdpartnr" -p 10 && HAVE_SWAP=yes # low priority, in case we have zram swap, prefer that) +for PART_DEV in $(get_all_with_id 82) '/dev/disk/by-partlabel/Linux\x20swap'; do + [ -e "$PART_DEV" ] || continue # Since Linux\x20swap is hard-coded and might not exist + if swapon "$PART_DEV" -p 10; then + HAVE_SWAP=yes # low priority, in case we have zram swap, prefer that) + echo -e "$PART_DEV\tswap\t\tswap\t\tdefaults\t 0 0" >> "/etc/fstab" + fi done # We use special non assigned partition type (id44) for harddisk scratch # space, thus no normal filesystem will be incidentally deleted or # corrupted HAVE_TEMP=no -for hdpartnr in $(sed -n -e "/ 44 /p" "/etc/disk.partition" | sed -e "s/[[:space:]].*//"); do +for PART_DEV in $(get_all_with_id 44) '/dev/disk/by-partlabel/OpenSLX-ID44'; do + [ -e "$PART_DEV" ] || continue # Since OpenSLX-ID44 is hard-coded and might not exist # check for supported filesystem and formatter - if diskfm "$hdpartnr"; then - # echo "$hdpartnr is mounted to /mnt/tmp at $(sysup)" >/tmp/tmpready - mount_temp "$mopt" "$hdpartnr" || continue - echo -e "${hdpartnr}\t/tmp\t\tauto\t\tnoexec\t 0 0" >> "/etc/fstab" + if format_disk "$PART_DEV"; then + # echo "$PART_DEV is mounted to /mnt/tmp at $(sysup)" >/tmp/tmpready + mount_temp "$MOUNT_OPTIONS_SET_BY_FORMAT_DISK" "$PART_DEV" || continue + echo -e "${PART_DEV}\t/tmp\t\tauto\t\tnoexec\t 0 0" >> "/etc/fstab" HAVE_TEMP=yes break else @@ -123,44 +144,52 @@ for hdpartnr in $(sed -n -e "/ 44 /p" "/etc/disk.partition" | sed -e "s/[[:space fi # Made this non-forking, systemd should handle it - 2013-05-28 done -# Put detected linux partitions (83) into /etc/fstab with "noauto", special -# partition 45 (persistent scratch) to /var/scratch and 46 to /var/openslx -HAVE_PERSISTENT=no -for partid in 83 45 46 ; do - for hdpartnr in $(sed -n -e "/ ${partid} /p" "/etc/disk.partition" | sed -e "s/[[:space:]].*//"); do - if [ "${partid}" -eq 83 ]; then - mkdir -p "/media/${hdpartnr#/dev/*}" - echo -e "${hdpartnr}\t/media/${hdpartnr#/dev/*}\tauto\t\tnoauto,noexec\t 0 0" >> "/etc/fstab" - elif [ "${partid}" -eq 45 -a "$HAVE_PERSISTENT" = "no" ]; then - mkdir -p "$PERSISTENT" - if ! mount -t auto -o noexec "${hdpartnr}" "$PERSISTENT"; then - diskfm "$hdpartnr" "jfs xfs ext3" || continue - mount -t auto -o noexec "${hdpartnr}" "$PERSISTENT" || continue - fi - HAVE_PERSISTENT=yes - echo -e "${hdpartnr}\t${PERSISTENT}\tauto\t\tnoauto,noexec\t\t 0 0" >> "/etc/fstab" - elif [ "${partid}" -eq 46 ]; then - mkdir -p "/media/${hdpartnr#/dev/*}" - #mount -t auto ${hdpartnr} /mnt/media/${hdpartnr#/dev/*} \n\ - #test -d /mnt/media/${hdpartnr#/dev/*}/home && \ - # ln -sf /media/${hdpartnr#/dev/*} /var/home - echo -e "${hdpartnr}\t/media/${hdpartnr#/dev/*}\tauto\t\tnoauto\t\t 0 0" >> "/etc/fstab" - fi - done +# Put detected linux partitions (83) into /etc/fstab with "noauto" +HAVE_PARTITION_45=no +for PART_DEV in $(get_all_with_id 83); do + mkdir -p "/media/${PART_DEV#/dev/*}" + echo -e "${PART_DEV}\t/media/${PART_DEV#/dev/*}\tauto\t\tnoauto,noexec\t 0 0" >> "/etc/fstab" done -[ "$HAVE_PERSISTENT" = "no" -a -d "$PERSISTENT" ] && rm -f "$PERSISTENT" + +# special partition 45 (persistent scratch) to $MOUNT_POINT_45 +for PART_DEV in $(get_all_with_id 45); do + mkdir -p "$MOUNT_POINT_45" + if ! mount -t auto -o noexec "${PART_DEV}" "$MOUNT_POINT_45"; then + format_disk "$PART_DEV" "ext4 xfs jfs ext3" || continue + mount -t auto -o noexec "${PART_DEV}" "$MOUNT_POINT_45" || continue + fi + echo -e "${PART_DEV}\t${MOUNT_POINT_45}\tauto\t\tnoauto,noexec\t\t 0 0" >> "/etc/fstab" + HAVE_PARTITION_45=yes + break +done + +# and 46 to /media/devXX +for PART_DEV in $(get_all_with_id 46); do + mkdir -p "/media/${PART_DEV#/dev/*}" + #mount -t auto ${PART_DEV} /mnt/media/${PART_DEV#/dev/*} \n\ + #test -d /mnt/media/${PART_DEV#/dev/*}/home && \ + # ln -sf /media/${PART_DEV#/dev/*} /var/home + echo -e "${PART_DEV}\t/media/${PART_DEV#/dev/*}\tauto\t\tnoauto\t\t 0 0" >> "/etc/fstab" +done +if [ "$HAVE_PARTITION_45" = "no" ] && [ -d "$MOUNT_POINT_45" ]; then + rm -f -- "$MOUNT_POINT_45" +fi mount -a -# Make huge tmpfs if nothing could be mounted for /tmp +# Make tmpfs if nothing could be mounted for /tmp +# 2016-10-12: Use a sane size of 66% which should be generous enough and prevent the machine from +# just crashing if RAM is too full. We previously hugely oversized since vmware wants at least as +# much free space as the VMs RAM; however, this requirement can be disabled with a vmx setting, +# which we're now doing. if [ "$HAVE_TEMP" = "no" ]; then - mount_temp -t tmpfs -o size=60G none - slxlog "partition-temp" "Running /tmp on tmpfs only!" "/etc/disk.partition" + mount_temp -t tmpfs -o size=66% none + slxlog "partition-temp" "Running /tmp on tmpfs only!" "$PARTITION_FILE" fi if [ "$HAVE_SWAP" = "no" ]; then TOTAL_RAM=$(grep ^MemTotal /proc/meminfo | awk '{print $2}') if [ -n "$TOTAL_RAM" ] && [ "$TOTAL_RAM" -lt "3000000" ]; then - slxlog "partition-swap" "Have no (formatted) swap partition, using zram swap only!" "/etc/disk.partition" + slxlog "partition-swap" "Have no (formatted) swap partition, using zram swap only!" "$PARTITION_FILE" fi fi diff --git a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-setup_slx_addons b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-setup_slx_addons index 8fb2579a..8d4d2d1a 100755 --- a/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-setup_slx_addons +++ b/core/rootfs/rootfs-stage32/data/opt/openslx/scripts/systemd-setup_slx_addons @@ -15,8 +15,6 @@ # ###################################################################################### -export PATH=$PATH:/opt/openslx/bin:/opt/openslx/sbin - # read global OpenSLX config . /opt/openslx/config || { echo "Could not source config!"; exit 23; } diff --git a/core/rootfs/rootfs-stage32/module.build b/core/rootfs/rootfs-stage32/module.build index 4fbc26b5..b4cba74f 100644 --- a/core/rootfs/rootfs-stage32/module.build +++ b/core/rootfs/rootfs-stage32/module.build @@ -47,10 +47,16 @@ build() { done done - for FILE in ${REQUIRED_DIRECTORIES} + for FILE in /etc/ssl/certs do [ ! -d ${FILE} ] && perror "Missing required directory $FILE" echo ${FILE} >> "${FILELIST}" + ( + IFS=$'\n' + for file in $(find "${FILE}" -type l); do + get_link_chain "${file}" >> "${FILELIST}" + done + ) done for FILE in ${REQUIRED_FILES} do diff --git a/core/rootfs/rootfs-stage32/module.conf b/core/rootfs/rootfs-stage32/module.conf index 0e62ab55..fae2c25b 100644 --- a/core/rootfs/rootfs-stage32/module.conf +++ b/core/rootfs/rootfs-stage32/module.conf @@ -20,10 +20,10 @@ REQUIRED_BINARIES=" mkfs.ext4 blkid modprobe - insmod - lsmod - rm - kill + insmod + lsmod + rm + kill ps scp ssh @@ -33,6 +33,7 @@ REQUIRED_BINARIES=" dirname mkdosfs iptables + ip6tables rdns find rpcbind @@ -43,9 +44,9 @@ REQUIRED_BINARIES=" grep date cat - ls - awk - sed + ls + awk + sed " REQUIRED_LIBRARIES=" libcap diff --git a/core/rootfs/rootfs-stage32/module.conf.ubuntu b/core/rootfs/rootfs-stage32/module.conf.ubuntu index 77c68cef..fe766a7a 100644 --- a/core/rootfs/rootfs-stage32/module.conf.ubuntu +++ b/core/rootfs/rootfs-stage32/module.conf.ubuntu @@ -12,10 +12,9 @@ REQUIRED_CONTENT_PACKAGES=" REQUIRED_BINARIES+=" openssl " -REQUIRED_DIRECTORIES=" +REQUIRED_SYSTEM_FILES+=" /lib/xtables " REQUIRED_FILES+=" /etc/X11/app-defaults/Xvidtune - /usr/lib/ssl/openssl.cnf " diff --git a/core/targets/stage31/kernel b/core/targets/stage31/kernel index 044f086d..1369e8ff 120000 --- a/core/targets/stage31/kernel +++ b/core/targets/stage31/kernel @@ -1 +1 @@ -../../modules/kernel
\ No newline at end of file +../../modules/kernel-vanilla
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/alsa b/core/targets/stage32-bwlp/alsa new file mode 120000 index 00000000..7e13d263 --- /dev/null +++ b/core/targets/stage32-bwlp/alsa @@ -0,0 +1 @@ +../../modules/alsa
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/beamergui b/core/targets/stage32-bwlp/beamergui new file mode 120000 index 00000000..5e863316 --- /dev/null +++ b/core/targets/stage32-bwlp/beamergui @@ -0,0 +1 @@ +../../modules/beamergui
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/cpugovernor b/core/targets/stage32-bwlp/cpugovernor new file mode 120000 index 00000000..544c1e19 --- /dev/null +++ b/core/targets/stage32-bwlp/cpugovernor @@ -0,0 +1 @@ +../../modules/cpugovernor
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/cron b/core/targets/stage32-bwlp/cron new file mode 120000 index 00000000..39164da5 --- /dev/null +++ b/core/targets/stage32-bwlp/cron @@ -0,0 +1 @@ +../../modules/cron
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/cups b/core/targets/stage32-bwlp/cups new file mode 120000 index 00000000..0ff7101d --- /dev/null +++ b/core/targets/stage32-bwlp/cups @@ -0,0 +1 @@ +../../modules/cups
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/dbus b/core/targets/stage32-bwlp/dbus new file mode 120000 index 00000000..dd148715 --- /dev/null +++ b/core/targets/stage32-bwlp/dbus @@ -0,0 +1 @@ +../../modules/dbus
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/dhcpc-busybox b/core/targets/stage32-bwlp/dhcpc-busybox new file mode 120000 index 00000000..ea3634e6 --- /dev/null +++ b/core/targets/stage32-bwlp/dhcpc-busybox @@ -0,0 +1 @@ +../../modules/dhcpc-busybox
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/dmidecode b/core/targets/stage32-bwlp/dmidecode new file mode 120000 index 00000000..608c2bb5 --- /dev/null +++ b/core/targets/stage32-bwlp/dmidecode @@ -0,0 +1 @@ +../../modules/dmidecode
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/dnbd3 b/core/targets/stage32-bwlp/dnbd3 new file mode 120000 index 00000000..fa80b45c --- /dev/null +++ b/core/targets/stage32-bwlp/dnbd3 @@ -0,0 +1 @@ +../../modules/dnbd3
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/dunst b/core/targets/stage32-bwlp/dunst new file mode 120000 index 00000000..e3927e25 --- /dev/null +++ b/core/targets/stage32-bwlp/dunst @@ -0,0 +1 @@ +../../modules/dunst
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/german b/core/targets/stage32-bwlp/german new file mode 120000 index 00000000..4469f96e --- /dev/null +++ b/core/targets/stage32-bwlp/german @@ -0,0 +1 @@ +../../modules/german
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/hardware-stats b/core/targets/stage32-bwlp/hardware-stats new file mode 120000 index 00000000..3e5e637b --- /dev/null +++ b/core/targets/stage32-bwlp/hardware-stats @@ -0,0 +1 @@ +../../modules/hardware-stats
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/idleaction b/core/targets/stage32-bwlp/idleaction new file mode 120000 index 00000000..09fd9493 --- /dev/null +++ b/core/targets/stage32-bwlp/idleaction @@ -0,0 +1 @@ +../../modules/idleaction
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/iptables-helper b/core/targets/stage32-bwlp/iptables-helper new file mode 120000 index 00000000..e449282d --- /dev/null +++ b/core/targets/stage32-bwlp/iptables-helper @@ -0,0 +1 @@ +../../modules/iptables-helper
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/kdm b/core/targets/stage32-bwlp/kdm new file mode 120000 index 00000000..727ed5b5 --- /dev/null +++ b/core/targets/stage32-bwlp/kdm @@ -0,0 +1 @@ +../../modules/kdm
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/kdm-theme-bwlp b/core/targets/stage32-bwlp/kdm-theme-bwlp new file mode 120000 index 00000000..db1d5251 --- /dev/null +++ b/core/targets/stage32-bwlp/kdm-theme-bwlp @@ -0,0 +1 @@ +../../modules/kdm-theme-bwlp
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/kernel b/core/targets/stage32-bwlp/kernel new file mode 120000 index 00000000..1369e8ff --- /dev/null +++ b/core/targets/stage32-bwlp/kernel @@ -0,0 +1 @@ +../../modules/kernel-vanilla
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/nscd b/core/targets/stage32-bwlp/nscd new file mode 120000 index 00000000..d7e411d2 --- /dev/null +++ b/core/targets/stage32-bwlp/nscd @@ -0,0 +1 @@ +../../modules/nscd
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/openbox b/core/targets/stage32-bwlp/openbox new file mode 120000 index 00000000..0fb8d86d --- /dev/null +++ b/core/targets/stage32-bwlp/openbox @@ -0,0 +1 @@ +../../modules/openbox
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/pam b/core/targets/stage32-bwlp/pam new file mode 120000 index 00000000..588acdbf --- /dev/null +++ b/core/targets/stage32-bwlp/pam @@ -0,0 +1 @@ +../../modules/pam
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/pam-bwidm b/core/targets/stage32-bwlp/pam-bwidm new file mode 120000 index 00000000..b6847cd8 --- /dev/null +++ b/core/targets/stage32-bwlp/pam-bwidm @@ -0,0 +1 @@ +../../modules/pam-bwidm
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/pam-common-share b/core/targets/stage32-bwlp/pam-common-share new file mode 120000 index 00000000..dc5084a2 --- /dev/null +++ b/core/targets/stage32-bwlp/pam-common-share @@ -0,0 +1 @@ +../../modules/pam-common-share
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/polkit b/core/targets/stage32-bwlp/polkit new file mode 120000 index 00000000..0ad0b111 --- /dev/null +++ b/core/targets/stage32-bwlp/polkit @@ -0,0 +1 @@ +../../modules/polkit
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/printergui b/core/targets/stage32-bwlp/printergui new file mode 120000 index 00000000..6ccbb628 --- /dev/null +++ b/core/targets/stage32-bwlp/printergui @@ -0,0 +1 @@ +../../modules/printergui
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/pvs2 b/core/targets/stage32-bwlp/pvs2 new file mode 120000 index 00000000..01875515 --- /dev/null +++ b/core/targets/stage32-bwlp/pvs2 @@ -0,0 +1 @@ +../../modules/pvs2
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/redsocks b/core/targets/stage32-bwlp/redsocks new file mode 120000 index 00000000..0740c53b --- /dev/null +++ b/core/targets/stage32-bwlp/redsocks @@ -0,0 +1 @@ +../../modules/redsocks
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/rootfs-stage32 b/core/targets/stage32-bwlp/rootfs-stage32 new file mode 120000 index 00000000..96dcbb86 --- /dev/null +++ b/core/targets/stage32-bwlp/rootfs-stage32 @@ -0,0 +1 @@ +../../rootfs/rootfs-stage32
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/rsyslogd b/core/targets/stage32-bwlp/rsyslogd new file mode 120000 index 00000000..339d02f8 --- /dev/null +++ b/core/targets/stage32-bwlp/rsyslogd @@ -0,0 +1 @@ +../../modules/rsyslogd
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/run-virt b/core/targets/stage32-bwlp/run-virt new file mode 120000 index 00000000..1e4a476c --- /dev/null +++ b/core/targets/stage32-bwlp/run-virt @@ -0,0 +1 @@ +../../modules/run-virt
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/screen-standby b/core/targets/stage32-bwlp/screen-standby new file mode 120000 index 00000000..7930482f --- /dev/null +++ b/core/targets/stage32-bwlp/screen-standby @@ -0,0 +1 @@ +../../modules/screen-standby
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/smartctl b/core/targets/stage32-bwlp/smartctl new file mode 120000 index 00000000..3a48434f --- /dev/null +++ b/core/targets/stage32-bwlp/smartctl @@ -0,0 +1 @@ +../../modules/smartctl
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/smbclient b/core/targets/stage32-bwlp/smbclient new file mode 120000 index 00000000..9fed855f --- /dev/null +++ b/core/targets/stage32-bwlp/smbclient @@ -0,0 +1 @@ +../../modules/smbclient
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/sshd b/core/targets/stage32-bwlp/sshd new file mode 120000 index 00000000..56b4e4b5 --- /dev/null +++ b/core/targets/stage32-bwlp/sshd @@ -0,0 +1 @@ +../../modules/sshd
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/sssd b/core/targets/stage32-bwlp/sssd new file mode 120000 index 00000000..753208d8 --- /dev/null +++ b/core/targets/stage32-bwlp/sssd @@ -0,0 +1 @@ +../../modules/sssd
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/systemd b/core/targets/stage32-bwlp/systemd new file mode 120000 index 00000000..2dc58bd3 --- /dev/null +++ b/core/targets/stage32-bwlp/systemd @@ -0,0 +1 @@ +../../modules/systemd
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/udisks b/core/targets/stage32-bwlp/udisks new file mode 120000 index 00000000..06e7da5f --- /dev/null +++ b/core/targets/stage32-bwlp/udisks @@ -0,0 +1 @@ +../../modules/udisks
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/vmchooser2 b/core/targets/stage32-bwlp/vmchooser2 new file mode 120000 index 00000000..bfdabcb7 --- /dev/null +++ b/core/targets/stage32-bwlp/vmchooser2 @@ -0,0 +1 @@ +../../modules/vmchooser2
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/x11vnc b/core/targets/stage32-bwlp/x11vnc new file mode 120000 index 00000000..eb755d19 --- /dev/null +++ b/core/targets/stage32-bwlp/x11vnc @@ -0,0 +1 @@ +../../modules/x11vnc
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/xorg b/core/targets/stage32-bwlp/xorg new file mode 120000 index 00000000..a9494860 --- /dev/null +++ b/core/targets/stage32-bwlp/xorg @@ -0,0 +1 @@ +../../modules/xorg
\ No newline at end of file diff --git a/core/targets/stage32-bwlp/xscreensaver b/core/targets/stage32-bwlp/xscreensaver new file mode 120000 index 00000000..156ea38f --- /dev/null +++ b/core/targets/stage32-bwlp/xscreensaver @@ -0,0 +1 @@ +../../modules/xscreensaver/
\ No newline at end of file diff --git a/core/targets/vmware/kernel b/core/targets/vmware/kernel index 044f086d..1369e8ff 120000 --- a/core/targets/vmware/kernel +++ b/core/targets/vmware/kernel @@ -1 +1 @@ -../../modules/kernel
\ No newline at end of file +../../modules/kernel-vanilla
\ No newline at end of file |