Kategorien

Virtualbox und Intrepid – das perfekte Setup – Desktop integrieren

Nach der Vorstellung des perfekten Netzwerk-Setups zur Integration von Virtualbox in Intrepid, wird nun im zweiten Schritt die virtuelle Maschine in den Ubuntu-Desktop integriert. Der Desktop der virtuellen Maschine soll dabei auf einer Arbeitsfläche unter Ubuntu erscheinen. Damit das folgende Skript funktioniert, müssen zwei Bedingungen erfüllt sein.

  1. Die virtuelle Maschine antwortet auf Pings. Bei Windows XP als Gastsystem muss man das unter Start>Systemsteuerung>Windows Firewall unter dem Reiter Erweitert aktivieren. Dort bei ICMP auf Einstellungen klicken und bei Eingehende Echo-Anforderung zulassen das Häkchen setzen.
  2. In Virtualbox ist der VRDP-Zugriff aktiviert. Diesen aktiviert man, indem man über Anwendungen>Systemwerkzeuge>Sun xVM Virtualbox die grafische VirtualBox-Oberfläche startet, die entsprechende virtuelle Maschine auswählt und auf Ändern klickt. Im erscheinenden Konfigurationsdialog unter Fernsteuerung das Häkchen bei VRDP-Server aktivieren setzt. Der Serverport sollte auf 3389 und die Authentisierungsmethode auf Null gesetzt sein. Damit muss man kein Benutzername und Passwort zum Einloggen angeben, allerdings kann so natürlich jeder auf die virtuelle Maschine zugreifen. Um das zu verhindern, empfehle ich dringend einen entsprechenden Firewall-Eintrag zu setzen, der den Zugriff auf den Port 3389 auf localhost beschränkt.

So nun aber zu dem Skript launchvm.sh, das die virtuelle Maschine startet und danach mit rdesktop auf die virtuelle Maschine verbindet:

#!/bin/bash
# launchvm.sh by Markus Effinger, December 2008
# latest version available at
# http://www.effinger.org/blog/2008/12/07/virtualbox-und-intrepid-das-perfekte-setup-desktop-integrieren/
#
# create your own custom app launchers by calling this script with different app arguments
# ORIGINAL SCRIPT FROM: waspbloke, http://ohioloco.ubuntuforums.org/showthread.php?t=939183 

# change these vars to reflect your own setup
VirtualMachine="Windows XP Frodo"
GuestIP="192.168.0.70" #The external ip of the Virtual Machine
VideoMode="setvideomodehint 1024 720 16" #for example setvideomodehint 1280 720 16

#Determine UUID of the specified Virtual Machine
VMUUID=`VBoxManage showvminfo "$VirtualMachine" | grep "^UUID" | awk '{print $2}'`
# check if VM is already running

# if VM not running start the VM and wait while it boots
if [ $(VBoxManage -nologo list runningvms | grep "$VMUUID" | wc -l) = 0 ]; then
	VBoxHeadless -startvm "$VirtualMachine" &
	echo "Please wait, starting VM $VirtualMachine"
	# Wait until the graphics mode of the VM is ready - otherwise VRDP will not work
	sleep 30
fi

if [ "$VideoMode" != "" ] ; then
	echo "Setting video mode.."
	VBoxManage controlvm "$VirtualMachine" $VideoMode
fi

# check if VM is ready to connect
echo "VM started, pinging $GuestIP .."

# Waiting until the ping works is not really necessary, but ensures, that the guest is ready to work with..
until ping -c 1 "$GuestIP"
do
	echo "ping not succesful"
	sleep 5
done

# now we can fire up rdesktop
echo "Launching rdesktop session..."
#You can launch in seamlessrdp mode if you want to...
rdesktop localhost:3389 -rclipboard:PRIMARYCLIPBOARD -rsound -DP -z -5 -xl

Die Variablen des Skripts müssen selbstverständlich angepasst werden:

  • VirtualMachine: Name der virtuellen Maschine, die gestartet werden soll
  • GuestIP: IP-Addresse des Gastsystems – muss auf pings antworten
  • VideoMode: Über diese Variable passt man die Fenstergröße von rdesktop an. Üblicherweise möchte man, dass rdesktop die gesamte Arbeitsfläche ausfüllt. In meinem Fall habe ich eine Auflösung von 1024×768 und zwei Panels jeweils 24 Pixel hoch, so dass die optimale Größe bei mir 1024×720 beträgt. Folglich ist diese Variable auf setvideomodehint 1024 720 16 gesetzt. Die 16 stehen dabei für eine Farbtiefe von 16 Bit – mehr geht bei RDP nicht.

Beim Ausführen von launchvm.sh startet nun jedes Mal die virtuelle Maschine und anschließend wird auf diese über rdesktop zugegriffen. Ich empfehle eine Startverknüpfung zu launchvm.sh anzulegen. Ein nettes Windows XP-Logo für die Startverknüpfung zu launchvm.sh findet sich bei Ellogon.

Im Normalfall möchte man rdesktop auf einer festen Arbeitsfläche haben. Um das zu erreichen, wird über Alt-F2 das Programm ccsm gestartet. Unter der Rubrik Fensterverwaltung klicken wir auf Place Windows, wählen den Reiter Fixed Window Placement aus. Dann auf Neu klicken (unter Windows with fixed viewport) und im erscheinenden Dialogfeld als Text

(class=rdesktop) & title=rdesktop - localhost

eingeben. Mit den XViewport und YViewport Schiebern lässt sich nun die gewünschte Arbeitsfläche auswählen.

Damit sind wir am Ende angelangt. Es gibt zwar noch alternative Methoden, um Windows XP im Speziellen in den Ubuntu Desktop zu integrieren (z.B.  über Seamlessrdp, siehe dazu auch einen Wiki-Eintrag, weitere Möglichkeiten sind im Ubuntu-Forum aufgelistet), aber diese hier ist mit die stabilste und auch für andere Gastsysteme gültig.

WordPress Syntax Highlighting mit WP-Syntax

Jeder, der in seinem Blog Quellcode, Shell-Befehle und dergleichen veröffentlichen möchte, kommt meiner Meinung nach nicht um ein Plugin herum, das den Quelltext optisch aufbereitet. Inzwischen gibt es für WordPress etliche Plugins, die Syntax Highlighting anbieten. Beispielhaft seien hier SyntaxHighlighter, Code Markup und WP-Syntax genannt. SyntaxHighlighter wollte ich nicht verwenden, weil es Javascript-basiert ist und deshalb nicht sichergestellt ist, dass auch Suchmaschinen, den entsprechenden Inhalt finden. Da mir der Funktionsumfang von Code Markup zu gering erschien habe ich mich schließlich auch aufgrund der Vielfalt an unterstützten Sprachen für WP-Syntax entschieden. Dieses konvertiert Sonderzeichen (z.B. „>“) in den entsprechenden HTML-Code (z.B. „>“). Beim Schreiben von Artikeln mit der WordPress-Weboberfläche wird im WYSIWYG-Modus allerdings bereits eine entsprechende Konvertierung vorgenommen, so dass man als Resultat im Artikel den HTML-Code angezeigt bekommt. Um dieses Problem zu umgehen, habe ich eine Lösung von Gergely Hodicska gefunden, die es zudem ermöglicht, den Quellcode noch komfortabler einzugeben. Im ersten Schritt wird die wp-content/plugins/wp-syntax/wp-syntax.php analog zu dem Vorschlag von Martin bzw. Shantanu so modifiziert, dass die fälschlicherweise vom WYSIWYG-Editor in HTML-Codes konvertierten Sonderzeichen wiederhergestellt werden:

function wp_syntax_code_trim($code)
{
    // special ltrim b/c leading whitespace matters on 1st line of content
    $code = preg_replace("/^\s*\n/siU", "", $code);
    $code = rtrim($code);
	/* Insertion Code Start */
	// MRi: changes to retranslate html code tags into the normal
	// characters for geshi.
	$code = strip_tags($code);
	if (PHP_VERSION > 5.0)
	{
		$code = html_entity_decode($code, ENT_QUOTES, "UTF-8");
	}
	else
	{
		$arrSearch = array("<", ">", " ", "&");
		$arrReplace = array("<", ">", " ", "&");
		$code = str_replace($arrSearch, $arrReplace, $code);
	}
	/* Insertion Code End */
    return $code;
}

Nun müssen aber zwangsweise alle Sonderzeichen auch in die HTML-Codes konvertiert werden – also nicht nur, wenn man im WYSIWYG-Editor arbeitet. Diese Konvertierung erledigt man am Besten durch das Anlegen eines neuen Buttons namens „pre“ im HTML-Modus der Weboberfläche. Dazu müssen die Dateien wp-includes/js/quicktags.js und wp-includes/js/tinymce/tiny_mce_config.php abgeändert werden.
quicktags.js:

/* Insertion Code Start */
edButtons[edButtons.length] =
new edButton('ed_pre'
,'pre'
,'<pre>'
,'</pre>'
,'f'
);
/* Insertion Code End */
/* Insertion Code Start */
// Prompt for syntax highlighting parameter, and return the appropriate start tag.
// TODO: l10n support.
function edGetPreStartTag() {
	var syntaxInfo = prompt('Please insert syntax highlighting information:'+"\n"+'language[,line number]!', 'php,1').split(',');
	return '<pre lang="'+syntaxInfo[0]+'"'+(syntaxInfo[1] != undefined ? ' line="'+syntaxInfo[1]+'"' : '')+'>'+"\n";
}

function edhtmlspecialchars(p_string) {
	p_string = p_string.replace(/&/g, '&amp;');
	p_string = p_string.replace(/</g, '&lt;');
	p_string = p_string.replace(/>/g, '&gt;');
	p_string = p_string.replace(/"/g, '&quot;');
//	p_string = p_string.replace(/'/g, '&#039;');
	return p_string;
};

/* Insertion Code End */

// insertion code

function edInsertTag(myField, i) {
	//IE support
	if (document.selection) {
		myField.focus();
	    sel = document.selection.createRange();
		if (sel.text.length > 0) {
			/* Insertion Code Start */
			if (edButtons[i].id == 'ed_pre') {
				sel.text =edhtmlspecialchars(sel.text);
				edButtons[i].tagStart = edGetPreStartTag();
			}
			/* Insertion Code End */
			sel.text = edButtons[i].tagStart + sel.text + edButtons[i].tagEnd;
		}
		else {
			if (!edCheckOpenTags(i) || edButtons[i].tagEnd == '') {
				/* Insertion Code Start */
				if (edButtons[i].id == 'ed_pre') {
					edButtons[i].tagStart = edGetPreStartTag();
				}
				/* Insertion Code End */
				sel.text = edButtons[i].tagStart;
				edAddTag(i);
			}
			else {
				sel.text = edButtons[i].tagEnd;
				edRemoveTag(i);
			}
		}
		myField.focus();
	}
	//MOZILLA/NETSCAPE support
	else if (myField.selectionStart || myField.selectionStart == '0') {
		var startPos = myField.selectionStart;
		var endPos = myField.selectionEnd;
		var cursorPos = endPos;
		var scrollTop = myField.scrollTop;

		if (startPos != endPos) {
			/* Modification Code Start */
			var selectedText = myField.value.substring(startPos, endPos);
			var selectedTextLengthGrowth = 0;
			if (edButtons[i].id == 'ed_pre') {
				edButtons[i].tagStart = edGetPreStartTag();
				selectedTextLengthGrowth = selectedText.length;
				selectedText = edhtmlspecialchars(selectedText);
				selectedTextLengthGrowth = selectedText.length - selectedTextLengthGrowth;
			}
			myField.value = myField.value.substring(0, startPos)
			              + edButtons[i].tagStart
			              + selectedText
			              + edButtons[i].tagEnd
			              + myField.value.substring(endPos, myField.value.length);
			cursorPos += edButtons[i].tagStart.length + edButtons[i].tagEnd.length + selectedTextLengthGrowth;
			/* Modification Code End */
		}
		else {
			if (!edCheckOpenTags(i) || edButtons[i].tagEnd == '') {
				/* Insertion Code Start */
				if (edButtons[i].id == 'ed_pre') {
					edButtons[i].tagStart = edGetPreStartTag();
				}
				/* Insertion Code End */
				myField.value = myField.value.substring(0, startPos)
				              + edButtons[i].tagStart
				              + myField.value.substring(endPos, myField.value.length);
				edAddTag(i);
				cursorPos = startPos + edButtons[i].tagStart.length;
			}
			else {
				myField.value = myField.value.substring(0, startPos)
				              + edButtons[i].tagEnd
				              + myField.value.substring(endPos, myField.value.length);
				edRemoveTag(i);
				cursorPos = startPos + edButtons[i].tagEnd.length;
			}
		}
		myField.focus();
		myField.selectionStart = cursorPos;
		myField.selectionEnd = cursorPos;
		myField.scrollTop = scrollTop;
	}
	else {
		if (!edCheckOpenTags(i) || edButtons[i].tagEnd == '') {
			/* Insertion Code Start */
			if (edButtons[i].id == 'ed_pre') {
				edButtons[i].tagStart = edGetPreStartTag();
			}
			/* Insertion Code End */
			myField.value += edButtons[i].tagStart;
			edAddTag(i);
		}
		else {
			myField.value += edButtons[i].tagEnd;
			edRemoveTag(i);
		}
		myField.focus();
	}
}

tiny_mce_config.php:

/* Code Modification Start */
/* 'pre' button added for wp-syntax */
$mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', '|', 'bullist', 'numlist', 'blockquote', 'pre', '|', 'justifyleft', 'justifycenter', 'justifyright', '|', 'link', 'unlink', 'wp_more', '|', 'spellchecker', 'fullscreen', 'wp_adv' ));
$mce_buttons = implode($mce_buttons, ',');
/* Code Modification End */

Die eingefügten/veränderten Abschnitte sind zwar jeweils durch Kommentare kenntlich gemacht, aber mit entsprechenden diff-Dateien lassen sich die Dateien doch am Besten patchen. Die diff-Dateien wurden unter Verwendung der von WordPress 2.6.5 und WP-Syntax 0.9.1 erstellt. Bitte unbedingt beachten, dass die durchgeführten Modifikationen beim Update von WordPress bzw. WP-Syntax nochmals durchgeführt werden müssen.

Meinen Quellcode füge ich nach den Modifikationen immer so ein:

  1. Quellcode in Zwischenablage kopieren
  2. In der WordPress-Weboberfläche in den HTML-Modus wechseln
  3. Quellcode aus der Zwischenablage einfügen
  4. Eingefügten Quellcode markieren
  5. Auf den Button pre klicken
  6. Im erscheinenden Dialog die Programmiersprache und falls gewünscht die Zeilennummer durch Komma getrennt angeben
  7. Zurück in den visuellen Modus wechseln

Eine alternative Lösung für das Konvertierungsproblem in HTML-Entititäten ist der Ersatz des pre-Tags durch div-Tags.

.bash_profile und .bashrc

Ich war erstaunt darüber, dass ich beim Login via SSH und über das Gnome-Terminal einen unterschiedlichen Prompt angezeigt bekam. Wie sich nach dem Lesen des Artikels von Josh Staiger herausstellte, war die Ursache dafür, dass die Bash beim Login auf der Konsole (beispielsweise über ein physisches Terminal oder mit SSH und Telnet) die .bash_profile ausführt und beim Aufruf eines Terminals über einen Windowmanager wie Gnome oder KDE die .bashrc ausführt. Damit nun bei jedem Login – egal ob von Konsole oder in Gnome – alles identisch ist (Shell-Funktionen, Aliase, Prompt usw.) habe ich meine .bash_profile so angepasst, dass sie auf die .bashrc verweist:

# When using a console, either physically at the machine or
# using ssh, .bash_profile is executed.
# I want the same functions and aliases available as if logged in
# from a terminal within a windowing system such as KDE
# therefore we link to .bashrc if it is available
if [ -f ~/.bashrc ]; then
   source ~/.bashrc
fi

Hardware Clock Probleme mit Interpid Server und Virtualbox

Nach meinem Upgrade meiner Server-Installation von Hardy Heron auf Intrepid Ibex unter Virtualbox auf einem Windows-Host, bekam ich beim Hochfahren auf einmal die Fehlermeldung „Cannot access the Hardware Clock via any known method. Use the –debug option to see the details of our search for an access method.“ Der Aufruf von

hwclock --debug

brachte dann folgende Ausgabe:

hwclock from util-linux-ng 2.14
hwclock: Open of /dev/rtc failed, errno=2: No such file or directory.
No usable clock interface found.
Cannot access the Hardware Clock via any known method.

Beim Nachforschen zeigte sich, dass kein einziges /dev/rtc* Device vorhanden war, aber leider konnte ich auch kein passendes Kernelmodul finden, durch das das entsprechende Device verfügbar gewesen wäre. Wahrscheinlich ist das ein Bug von Intrepid. Als temporäre Maßnahme schafft es Abhilfe, in /etc/init.d/hwclockfirst.sh und /etc/init.d/hwlock.sh den Parameter HWCLOCKPARS auf –directisa zu setzen:

# Set this to any options you might need to give to hwclock, such
# as machine hardware clock type for Alphas.
HWCLOCKPARS="--directisa"

DVDs unter Intrepid Ibex (libdvdcss2 und w32codecs)

Eine Anleitung für den DVD-Support unter Hardy Heron hatte ich ja schon gepostet, nun ist Intrepid Ibex dran. Auch diesmal hilft das Medibuntu Repository weiter. Mit folgenden Befehlen aktivieren wir es als Software-Quelle (Anleitung von der offiziellen Medibuntu Wiki-Seite):

sudo wget http://www.medibuntu.org/sources.list.d/intrepid.list --output-document=/etc/apt/sources.list.d/medibuntu.list
sudo apt-get update && sudo apt-get install medibuntu-keyring && sudo apt-get update

Für die i386-Architektur führt man nun folgenden Befehl aus:

sudo apt-get install w32codecs libdvdcss2

Falls meinen einen 64-Bit Prozessor sein eigen nennt, führt man

sudo apt-get install w64codecs libdvdcss2

aus.