Quantcast
Channel: Michael Kofler – kofler.info
Viewing all 274 articles
Browse latest View live

20 Jahre Linux-Buch

$
0
0

Vor mehr als 21 Jahren kontaktierte mich der damalige Addison-Wesley-Verlag und sprach mit mir über ein Linux-Anwenderhandbuch. Ich fand die Idee inhaltlich reizvoll, aber ich sah keine Marktchancen. Linux war damals etwas für Freaks. Die brauchten kein benutzerfreundliches Handbuch, und gewöhnliche Anwender — also die Zielgruppe des Buchs — gäbe es keine. Dachte ich. Und erteilte Addison-Wesley eine Abfuhr.

Aber Addison-Wesley blieb hartnäckig. Die dortigen Lektoren wussten, dass ich schon lange mit Linux arbeitete, meine Bücher (damals vor allem im Visual-Basic-Umfeld) waren erfolgreich, kurzum: Es blieb beim Wunsch, dass ich ein Linux-Buch schreiben sollte. Und weil ich nun mal gern schreibe, und weil mir Linux damals schon viel Spaß machte, ließ ich mich schließlich überreden. Immer noch in der Meinung, dass ich nun zwar für Monate eine spannende Arbeit hätte, damit aber nicht viel Geld verdienen würde.

So kann man sich irren … Die erste Auflage meines Linux-Buchs mit aus heutiger Sicht bescheidenen 560 Seiten erschien im Februar 1995 und verkaufte sich von Anfang an prächtig.

linux-ersteauflage

Gerade einmal ein Jahr später folgte die zweite Auflage, danach Übersetzungen in mehrere Sprachen, noch mehr Auflagen, Sonderausgaben etc. Das Linux-Buch entwickelte sich zu meinem erfolgreichsten Buch, zu meinem Markenzeichen.

Warum Linux?

Heute hat jeder mit Linux zu tun — aber nicht jeder weiß es :-) Auf jedem Android-Handy läuft ein Linux-Kernel, jede Google-Anfrage wird von Linux-Servern beantwortet, jeder Amazon-Einkauf von Linux-Rechner verarbeitet, jede Dropbox-Datei ist Teil der von Linux dominierten Cloud.

Meine eigene Linux-Zeitrechnung begann 1993, noch bevor es Kernel 1.0 gab. Der Grund, weswegen ich damals auf einem PC Linux installierte, waren Arbeiten für ein anderes Buch. Ich verfasste gerade ein Maple-Handbuch. (Maple ist ein Computer-Algebrasystem.) Um das Buch zusammen mit unzähligen mathematischen Formeln ordentlich zu setzen, brauchte ich LaTeX. Und der einfachste Weg, ein vollständiges LaTeX-System aufzusetzen bestand daran, Linux einzusetzen.

Meine erste Linux-Distribution war Unifix Linux. Die norddeutsche Firma Unifix war bis 1997 ein Vertreter des blühenden Linux-Markts in Deutschland. Die Besonderheit der Distribution bestand darin, dass Linux weitestgehend von einer CD ausgeführt wurde. Nur die Teile der Distribution, die wirklich benötigt wurden, wurden auf die damals kleine Festplatte übertragen …

Berührungsängste zu Linux hatte ich keine: Im Rahmen meines Studiums hatte ich schon mehrfach mit UNIX-Systemen zu tun gehabt. Linux war in vielerlei Hinsicht ähnlich, vor allem aber moderner, besser anpassbar und viel preisgünstiger.

Mein Maple-Buch war das erste Buch, das ich selbst vollständig unter Linux schrieb und setzte: Editor Emacs, Satzsystem LaTeX, PS-Viewer Ghostscript. Das Buch war insofern ein Probedurchgang für das Linux-Buch, das ich ebenfalls von der ersten bis zur 14. Auflage im Editor Emacs verfasst und mit LaTeX gesetzt habe.

Von der ersten zur 14. Auflage

Unifix half mir beim Linux-Einstieg. Die Grundlage für die erste Auflage meines Linux-Buchs war aber die Distribution Slackware, die man damals wahlweise als Sammlung von Disketten (!) oder als CD kaufen konnten. Später folgten SUSE, Red Hat, Debian.

Den ersten elf Auflagen meiner Linux-Bücher lagen CDs bzw. später DVDs bei. Das Internet, das sich erst allmählich entwickelte, war noch langsam. Der Download einer Linux-Distribution war für Privatanwender zu langsam bzw. zu teuer. Die beigelegten CDs/DVDs waren insofern ein echter Bonus. Die beigelegten Distributionen sind gewissermaßen ein Streifzug durch die Linux-Geschichte:

  • 1. Auflage (1995): Slackware 2.1 mit Kernel 1.1.86
  • 4. Auflage (1999): SuSE 6.1 Evaluations-Version inkl. KDE 1.1 und Netscape Communicator
  • 7. Auflage (2004): SUSE Linux 10.0 OSS und Knoppix 4.0
  • 10. Auflage (2010): Ubuntu 10.10, openSUSE 11.3

2013 kam dann die Hiobsbotschaft des Addison-Wesley-Eigentümers Pearson Education: Addison-Wesley sollte schnellstmöglich abgewickelt werden. Der Verlag, für den ich 20 Jahre lang geschrieben hatte, gab es nicht mehr.

Was sich damals als Katastrophe darstellte, bewerte ich aus heutiger Sicht als Glücksfall: Nach nur kurzem Verhandeln entschied ich mich, mit meinem Linux-Buch zum Galileo-Verlag zu wechseln. Den schönen Verlagsnamen musste Galileo wenig später aufgeben, aber auch der Rheinwerk-Verlag zeichnet sich durch eine Agilität aus, die dem Addison-Wesley-Verlag zuletzt abhanden gekommen ist.

Die aktuelle Auflage

Seit wenigen Tagen ist nun die vierzehnte Auflage meines Linux-Buchs lieferbar: Vollständig aktualisiert stellt sie auf 1400 Seiten das Linux der Gegenwart mit seinen wichtigsten Distributionen und Werkzeugen dar. Details zum Buch sowie eine umfassende Leseprobe finden Sie hier.

linux2

PS: Ebenfalls fast fertig ist die Neuauflage der Linux-Kommandoreferenz (Erscheinungstermin Ende Januar 2016). Auch hierzu ein kleiner geschichtlicher Ausflug: Die Kommandoreferenz war von der 3. bis zur 9. Auflage als Kapitel im großen Linux-Buchs integriert. Aus Platzgründen haben wir uns 2010 zu einer Trennung zwischen dem Hauptbuch und der Kommandoreferenz entschieden. Diese hat mittlerweile ebenfalls einen Umfang von beinahe 500 Seiten erreicht …


root-Login-Problem mit MariaDB

$
0
0

In MariaDB gibt es das Authentifizierungs-Plugin unix_socket (Dokumentation). Heute bin ich das erste Mal darüber gestolpert, weil dieses Plugin bei einer MariaDB-Installation unter Ubuntu 15.10 standardmäßig aktiv ist.

An sich ist das eine feine Sache: Solange Sie als root bzw. mit sudo arbeiten, können Sie sich ohne Passwort beim MySQL-Server anmelden:

sudo mysql -u root
  Welcome to the MariaDB monitor.  Commands end with ; or \g.
  Your MariaDB connection id is 60
MariaDB [(none)]> status;
  Current user:     root@localhost
  ...

Wenn Sie gerade nicht root sind, scheitert der Login.

mysql -u root
  ERROR 1698 (28000): Access denied for user 'root'@'localhost'

Insofern ist MariaDB nun auch ohne Passwort abgesichert. Probleme treten nur dann auf, wenn Sie MariaDB auch dann administrieren möchten, ohne unter Linux als root oder mit sudo zu arbeiten.

MariaDB-root-Passwort setzen

Erfahrene Benutzer werden sagen: Kein Problem, es muss in der mysql.user-Datenbank eben ein Passwort für root definiert werden.

sudo mysql -u root
MariaDB [(none)]> update mysql.user set password=password('geheim') where user='root';
MariaDB [(none)]> flush privileges;

Von nun an müssen Sie sich wieder, wie in der Vergangenheit üblich , mit einem Passwort authentifizieren:

sudo mysql -u root -p
Enter password: *******

MySQL-Login als gewöhnlicher Benutzer

Das Problem ist nur: Wenn Sie unter Linux nicht als root eingeloggt sind bzw. sudo nicht verwenden, funktioniert der Login weiterhin nicht.

mysql -u root -p
Enter password: ******
ERROR 1698 (28000): Access denied for user 'root'@'localhost'

MariaDB führt jetzt nämlich zwei Authentifizierungsverfahren parallel aus: Der DB-Server überprüft, ob Sie als Linux-Benutzer root-Rechte haben UND ob Sie das korrekte Passwort angeben. Das Passwort alleine reicht nicht mehr.

Wenn sich MariaDB so verhalten soll wie früher, d.h., dass Sie sich nach einer Passwort-Angabe auch als gewöhnlicher Benutzer als MariaDB-root anmelden können, dann müssen Sie das unix_socket-Plugin deaktivieren. Werfen Sie zuerst einen Blick in die Tabelle mysql.user

sudo mysql -u root -p
  Enter password: *******
select user,host,password,plugin from mysql.user;
  +------+-----------+------------------------+-------------+
  | user | host      | password               | plugin      |
  +------+-----------+------------------------+-------------+
  | root | localhost | *geheimerhashcode      | unix_socket |
  | root | e320      | *geheimerhashcode      | unix_socket |
  | root | 127.0.0.1 | *geheimerhashcode      | unix_socket |
  | root | ::1       | *geheimerhashcode      | unix_socket |
  +------+-----------+------------------------+-------------+

… und setzen Sie die plugin-Spalte dann auf '':

update mysql.user set plugin='' where user='root';
flush privileges;

Von nun an funktioniert der Login wieder wie in der Vergangenheit.

Braucht Linux Swift? Oder braucht Apple Linux?

$
0
0

Vor eineinhalb Jahren hat Apple die Programmiersprache Swift vorgestellt. Wie man es sich von einer neuen Sprache erwartet, ist Swift modern und vereint in sich viele (die besten?) Features aus diversen anderen Programmiersprachen, kombiniert mit ein paar eigenen Ideen.

Wie jede neue Sprache leidet Swift noch unter einigen Kinderkrankheiten. Die größte besteht darin, dass die Sprache work in progress ist. Wer immer sich auf Swift einlässt, muss damit rechnen, dass sein Code schon mit der nächsten Swift-Version an neue Syntaxregeln oder veränderte Standardbibliotheken angepasst werden muss. (In der Apple-eigenen Entwicklungsumgebung Xcode funktioniert das zum Glück weitgehend automatisch.)

Trotz dieser Einschränkung ist Swift durchaus schon praxistauglich und wird bereits intensiv genutzt. Der Grund dafür ist leicht erklärt: Wer native Apps für iOS, OS X, die Apple Watch etc. programmieren will, hat nur die Wahl zwischen Objective C (uralt mit steinzeitlicher und abschreckender Syntax) und Swift. Apple erklärt dezidiert, die Zukunft heißt Swift. Da fällt die Entscheidung nicht schwer …

Swift ist jetzt ein Open-Source-Projekt

Gestern hat Swift eine Ankündigung vom vergangenen Sommer wahrgemacht: Swift wurde zusammen mit diversen Tools als Open-Source-Code freigegeben. Das Projekt wird auf GitHub gehostet, es gibt öffentliche Mailing-Listen und einen öffentlichen Bug-Tracker.

Was aus Linux-Sicht eine Selbstverständlichkeit ist, ist für Apple durchaus ein Paradigmenwechsel. Wenig andere IT-Firmen betreiben einen derartigen Aufwand, neue Entwicklungen so lang wie möglich geheim zu halten. Zumindest für Swift ist dies nun nicht mehr möglich.

Braucht Linux noch eine Programmiersprache?

Interessanterweise bevorzugt Apples Open-Source-Strategie Linux. Linux wird von Anfang an offiziell unterstützt, für Ubuntu gibt es sogar fertige Binärpakete. Apple stellt es der Community frei, auch Windows-Versionen von Swift zu entwickeln, engagiert sich dafür aber nicht selbst.

Da freut sich die Linux-Gemeinde aber, dass ihr noch eine Programmiersprache zur Verfügung steht!? Sie hat ja schon Erfahrung damit, nachdem Sun Java zum Open-Source-Projekt machte und später Microsoft auch C# und einen Teil des .NET-Frameworks freigab. Ein Blick auf Java und C# zeigt aber auch, dass die Begeisterung nicht grenzenlos ist:

  • Java im Webbrowser ist ein endloses Sicherheitsproblem und wie Flash im Aussterben begriffen. Auch zur Entwicklung von Desktop-Programmen (GUIs) hat sich Java nicht recht durchsetzen können, generell nicht, und noch weniger unter Linux. Ausgesprochen wichtig ist Java aber für den Server-Einsatz (J2EE) sowie zur Programmierung von Android-Apps. Praktisch ist Java natürlich auch für den Unterricht. Noch immer gilt Java (zumindest im deutschen Sprachraum) als die erste Programmiersprache. Praktisch also, dass Java auch unter Linux zur Verfügung steht.
  • C# und Mono wurden vorübergehend von einigen Gnome-Programmen genutzt. Die anfängliche Begeisterung ist mittlerweile aber verflogen. Heute ist C# unter Linux primär am (Web-)Server relevant, um ASP.NET auch unter Linux auszuführen.

Warum zeigt die Linux-Community nicht mit mehr Freude an so tollen und ausgereiften Programmiersprachen wie Java oder C#, die mit immensem (Kosten-)Aufwand von Firmen wie Oracle oder Microsoft vorangetrieben werden?

Vielleicht liegt es ganz einfach daran, dass es schon genug ausgezeichnete Programmiersprachen gibt. Die Linux-Kernelentwicklung wird bei C bleiben, die Anwendungsentwicklung für KDE und Gnome funktioniert mit C++ bzw. C. passabel, diverse Scripts lassen sich in der Bash oder, viel besser, mit Python entwicklen. Und für nahezu jede Spezialaufgabe stehen diverse weitere Programmiersprachen zur Auswahl.

Und jetzt kommt also Swift — und Sie spüren sicher schon meine Skepsis: Was bietet Swift, was Linux nicht ohnedies schon hat? Gegenwärtig nichts. In der aktuellen Form können Sie mit Swift unter Linux nicht viel mehr anfangen, als Algorithmen zu entwickeln. Interessant vielleicht für Unterricht und Lehre, aber nicht darüber hinaus.

Die Anbindung an das Linux-Umfeld, beispielsweise in Form einer GTK-Bibliothek, fehlt noch vollständig. Im Apple-Mikrokosmos stehen Swift-Programmierern unzählige Bibliotheken zur Auswahl; diese Bibliotheken sind aber nicht Teil der Open-Source-Strategie. Einzig die Foundation-Bibliothek, eine Art Standardbibliothek für recht elementare Aufgaben, soll unter Swift neu implementiert und ebenfalls als Open-Source-Code freigegeben werden.

Kurzum, ich bezweifle, dass Swift unter Linux auf Anhieb zum großen Erfolg wird. Vielleicht aber auf längere Sicht, denn …

Braucht Apple Linux?

Eine absurde Frage. Apple ist erfolgreich wie nie zuvor und schwimmt im Geld.

Aber auch im Apple-Kosmos gibt es schwarze Löcher. Eines ist die Server-Seite. Apple betreibt Server-Farmen in der Liga von Google und Amazon. Es ist wenig bekannt, welche Hard- und Software dabei eingesetzt wird. theRegister hat 2011 darüber spekuliert, es wäre eine Mischung aus Microsoft Azure und Amazon Services. Äußerst unwahrscheinlich ist auf jeden Fall, dass Apple eigene Hardware und OS X einsetzt. Apple hat den Server-Bereich in den letzten Jahren immer mehr vernachlässigt. So schön MacBooks, iMacs etc. sind — für das Rechenzentrum sind sie nicht konzipiert.

Die ganze schöne App(le)-Welt setzt eine solide dahinterliegende Server-Infrastruktur voraus. Und für App-Entwickler wäre es natürlich eine feine Sache, den Client (die App) und die Server-Seite (die Cloud) in der gleichen Programmiersprache entwickeln zu können. Wenn sich Swift unter Linux etabliert, wäre das möglich. Aus meiner Sicht liegt hier das größte Potential, die größte Chance für Swift unter Linux. Also Swift als Puzzleteil für eine Apple-Cloud unter Linux.

Ein zweiter Aspekt ist der Einsatz von Swift in Schulen, Universitäten — ein Segment, in dem Apple (zumindest in den USA) stark vertreten ist. Swift verkörpert moderne Sprachkonzepte und wäre insofern eine attraktive Wahl für den Unterricht. Aber solange Swift Apple-only ist (bzw. war), ist diese Option nicht praxistauglich. Keine Schule, keine Uni kann erwarten, dass jeder Schüler/Student Apple-Geräte nutzt. Gelingt es Swift aber, den Apple-Kosmos zu verlassen, dann hätte Swift als Unterrichtssprache eine reelle Chance. (Persönlich finde ich ja Python wegen seiner Einfachheit noch erheblich attraktiver, zumindest als erste Programmiersprache, aber sei’s drum.)

Fazit

In jedem Fall ist die Freigabe von Swift eine weitere Bestätigung für die Open-Source-Idee. Welche Strategien und Pläne Apple für Swift hat, darüber kann man (so wie ich) nur spekulieren. Langfristig könnte Swift aber zu einem durchaus interessanten Angebot selbst für eingefleischte Linux-Entwickler werden.

Pläne für Swift 3.0

$
0
0

Mit der Geheimniskrämerei ist es vorbei: Da Swift ein Open-Source-Projekt ist, verläuft die Entwicklung nun deutlich transparent. Dieser Beitrag fasst zusammen, was momentan zu Swift 3.0 bekannt ist. Diese Pläne werden sich natürlich ändern, und ich habe vor, diesen Beitrag bei Bedarf gelegentlich zu aktualisieren.

Zeitplan

Swift 3.0 ist für Herbst 2016 angekündigt. Das entspricht dem üblichen Release-Zyklus. Im Herbst werden üblicehrweise neue iPhones mit einer neuen iOS-Version ausgeliefert, und gleichzeitig wird es dann eben die aktualisierte Xcode-Version (8.0?) mit Swift 3.0 geben.

Die aktuelle Swift-Version in Xcode 7.2 ist 2.1.1 (Stand 11.12.2015):

xcrun swift -version
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Target: x86_64-apple-darwin15.2.0

Im Frühjahr 2016 soll noch Swift 2.2 erscheinen, wobei wie bei Swift 2.1 keine dramatischen Neuerungen geplant sind. Spannend wird es dann erst mit Swift 3.0 ..

Fundamentale Neuerungen in Swift 3.0

  • Binärkompatibilität: Auch Apple ist sich bewusst, dass die ständigen Änderungen in Swift für all jene, die schon produktiv mit Swift arbeiten, mühsam sind. Mit Version 3.0 sollen aber möglichst viele Interna und Strukturen so weit fixiert werden, dass nicht mehr bei jedem Update alles neu kompiliert werden soll.

  • Generics perfektionieren: Generische Typen sollen perfektioniert werden. Unter anderem soll Swift 3.0 rekursive Contraints unterstützen.

  • Verbesserte Schnittstellen zu den herkömmlichen Bibliotheken: Dass die Nutzung der für Objective C konzipierten Bibliotheken und XxxKits unter Swift sperrig, unübersichtlich und un-swift ist, bemerkt jeder, der auch nur wenige Tage mit Swift programmiert. Auch in meinem Buch habe ich das mehrfach kritisch angemerkt. Nicht einmal Apple kann deswegen alle Bibliotheken neu implementieren, aber immerhin gibt es Pläne, die Nutzung der vorhandenen Bibliotheken zu verbessern und die sprachliche Redundanz und Langatmigkeit zu mindern. Persönlich bin ich skeptisch, dass das in einem zufriedenstellenden Ausmaß gelingen wird, aber jede noch so kleine Verbesserung ist natürlich willkommen. (Eine Detailverbesserung soll darin bestehen, Kürzel wie NS zu eliminieren. Das wird den Code zwar nicht nennenswert verkürzen, aber immerhin frei von dem geschichtlich vorbelasteten Kürzel machen.)

  • Neue Foundation-Bibliothek: Die Foundation-Bibliothek soll in Swift neu implementiert werden. Das primäre Ziel ist hier weniger die Optimierung der Schnittstelle zu Swift. Vielmehr sollen für Linux, Windows etc. zumindest Grundfunktionen zur Verfügung gestellt werden. Momentan ähnelt Swift unter Linux ja einer Insel in der Mitte des Pazifik: Sie können damit Algorithmen testen, aber nicht viel mehr. Jeder Zugriff auf Funktionen/Bibliotheken des Betriebssystem ist mit hohem (Code-)Aufwand verbunden. Indem dem Swift eine Open-Source-Version der Foundation-Bibliothek zur Seite gestellt wird, soll dieses Problem ein wenig gemindert werden.

Sprachdetails in Swift 3.0

  • Schlüsselwörter als Parameternamen: Swift-Schlüsselwörter dürfen voraussichtlich schon ab Swift 2.2 als Parameternamen verwendet werden. Damit wäre insbesondere in als Parametername erlaubt. (Die Verwendung von Schlüsselwörtern ist schon jetzt möglich, allerdings müssen Schlüsselwörter in Backticks, also nach rechts gerichtete Apostrophe gestellt werden. Weitere Details sind hier nachlesen.)

  • var++, ++var, var--, --var ade: Die von C übernommenen Inkrement- und Dekrement-Operatoren sollen eliminiert werden. Der entsprechende Vorschlag argumentiert, dass der Einsatz dieser Operatoren verwirrend sein kann. Weiterhin verfügbar bleiben var+=1 und var-=1.

  • Keine Curried-Funktionen mehr: Swift bietet momentan die Möglichkeit, Curried Functions zu bilden, also Funktionen, bei denen vorerst nur ein Teil der Parameter festgelegt wird und der Rest weiter als Funktion genutzt werden kann. Diese relativ komplexe Syntax, auf die ich in meinem Buch gar nicht eingegangen bin, soll in Swift 3 eliminiert werden. Links: Swift-3-Proposal, Wikipedia, Introduction to Function Currying in Swift, Instance Methods are Curried Functions in Swift, Beschreibung im Swift-Buch von Apple

  • Weniger var, mehr let: Die Einsatzmöglichkeiten des Schlüsselworts var sollen reduziert werden. Gestrichen werden sollen func doSomething(var x:SomeType), if var, guard var, while var, case .Some(var x) und for var x in. Die entsprechenden Varianten ohne var bzw. mit explizitem let bleiben natürlich erhalten. Details: Proposal

  • Keine traditionellen for-Schleifen mehr? Noch nicht entschieden ist der folgende Vorschlag von Erica Sadun, die traditionelle for-Schleife ganz abzuschaffen. Persönlich sehe ich die Notwendigkeit dazu eigentlich nicht, aber die Umsetzung dieser Idee würde mich nicht überraschen.

  • Noch mehr Ideen: In der swift-evolution-Mailing-Liste werden gegenwärtig unzählige weitere Pläne diskutiert, von generischen Protokollen bis zur Abschaffung oder Umformulierung des ternären Operators. Wie groß die Chancen solcher von der Community formulierten Vorschläge ist, lässt sich gegenwärtig noch nicht abschätzen. Auch wenn Swift nun ein Open-Source-Projekt ist, wird Apple vermutlich eine strikte Kontrolle über den Entwicklungsprozess behalten.

Das ist nicht geplant

  • Multithreading/Asynchrone Programmierung: Swift soll nach dem aktuellen Planungsstand keine inhärenten Funktionen zur nebenläufigen Programmierung erhalten. Swift greift hierfür auf Foundation-Klassen, pthreads, libdispatch etc. zurück — und dabei soll es bis auf weiteres bleiben.

  • Bibliotheken: Apple kann und will nicht alle iOS-, OS-X-Bibliotheken etc. neu implementieren. Die Foundation-Bibliothek ist eine Ausnahme, alle anderen Bibliotheken sollen im Wesentlichen bleiben wie sie sind.

Quellen

Swift unter Ubuntu 15.10 ausprobieren

$
0
0

Swift steht für Ubuntu als tar-Archiv unter https://swift.org/download/ zum Download zur Verfügung. Die Installation ist einfach:

sudo apt-get install clang libicu-dev
wget https://swift.org/builds/ubuntu1510/swift-2.2-SNAPSHOT-2015-12-01-b/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10.tar.gz
tar xzf swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10.tar.gz
export PATH=$(pwd)/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10/usr/bin/:"${PATH}"
swift -version
  Swift version 2.2-dev (LLVM 46be9ff861, Clang 4deb154edc, Swift 778f82939c)
  Target: x86_64-unknown-linux-gnu

Der exakte Name des Download-Links und der Verzeichnisse wird sich bei zukünftigen Versionen natürlich ändern.

Hello World!

Um den Compiler zu testen, speichern Sie den folgenden Hello-World-Einzeiler in der Datei hello-world.swift:

print("Hello World!")

Dieses Programm kompilieren Sie nun mit swiftc und führen es aus:

swiftc hello-world.swift > hello-world
ls -l hello-world
  -rwxrwxr-x 1 kofler kofler 10112 Dez 12 16:11 hello-world
./hello-world
  Hello World!

Core Libraries nutzen

Grundsätzlich stehen die von OS X oder iOS bekannten Bibliotheken unter Linux nicht zur Verfügung. Apple arbeitet aber an einer Sammlung von Basisklassen, die in den Core Libraries) gebündelt werden. Diese Bibliotheken sollen Klassen aus der Foundation, sowie aus libdispatch und XCTest enthalten. Diese Bibliothek wird selbst in Swift entwickelt und steht bereits in einer ersten, sehr frühen und unvollständigen Version bereits als Open-Source-Code zur Verfügung. Wie weit die Arbeiten vorangeschritten sind, geht aus dieser Status-Seite hervor.

Wenn Sie Swift wie oben beschrieben installiert haben, stehen Ihnen die Core Libraries bereits zur Verfügung. Einen ersten Test können Sie mit diesem Mini-Programm durchführen. Es erzeugt ein NSDate-Objekt mit dem aktuellen Datum, extrahiert daraus Jahr, Monat und Tag und zeigt diese Daten an.

// Datei hello-core.swift
import Foundation
let cal = NSCalendar.currentCalendar()
let comps = cal.components(
  [.Day, .Month, .Year], fromDate: now)
print("Jahr: \(comps!.year)  Monat: \(comps!.month)  Tag: \(comps!.day)")

Hinweis: Die Klassennamen der Core Libraries sollen in naher Zukunft den Prefix NS verlieren. Das obige Beispiel muss dann entsprechend angepasst werden.

So kompilieren Sie das Programm und führen es aus:

swiftc hello-core.swift -o hello-core && ./hello-core
  Jahr: 2015  Monat: 12  Tag: 12

Das Kompilat ist klein, greift aber auf diverse Bibliotheken zurück:

ls -l hello-core
  -rwxrwxr-x 1 kofler kofler 14624 Dez 12 16:34 hello-core
ldd hello-core
    linux-vdso.so.1 =>  (0x00007ffdad5bb000)
    libswiftCore.so => [swift-install-path]/usr/lib/swift/linux/libswiftCore.so (0x00...)
    libFoundation.so => [swift-install-path]/usr/lib/swift/linux/libFoundation.so  (0x00...)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6  (0x00...)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6  (0x00...)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1  (0x00...)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6  (0x00...)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0  (0x00...)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2  (0x00...)
    libicuuc.so.55 => /usr/lib/x86_64-linux-gnu/libicuuc.so.55  (0x00...)
    libicui18n.so.55 => /usr/lib/x86_64-linux-gnu/libicui18n.so.55  (0x00...)
    libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0  (0x00...)
    /lib64/ld-linux-x86-64.so.2  (0x00...)
    libswiftGlibc.so => [swift-install-path]/usr/lib/swift/linux/libswiftGlibc.so  (0x00...)
    libicudata.so.55 => /usr/lib/x86_64-linux-gnu/libicudata.so.55  (0x00...)

CentOS 7.2

$
0
0

Mit beträchtlicher Verzögerung gegenüber RHEL 7.2 ist diese Woche CentOS 7.2 fertig geworden. Die Dateinamen der ISO-Images enthalten anstelle der Versionsnummer die Bezeichnung 15.11. CentOS verwendet für seine Medien seit Version 7 Ubuntu-ähnliche Versionsnummern. Ein wenig schleierhaft ist nur, warum die Download-Medien 15.11 und nicht 15.12 im Dateinamen enthalten. Die Freigabe der Medien erfolgte definitiv erst im Dezember.

CentOS 7.2 ist ein inkrementelles Update der CentOS-7-Reihe, d.h. durch regelmäßige Updates wird jedes CentOS-7-System automatisch auf Version 7.2 aktualisiert. Sollten Sie nur sehr unregelmäßig Updates durchführen, kann das Update allerdings scheitern. Abhilfe schafft dann die Deaktivierung der Delta-RPM-Funktion, wie ich dies schon vor einem halben Jahr hier beschrieben habe.

Bei Neuinstallationen muss nach dem ersten Start eine Lizenzvereinbarung akzeptiert werden. Die Dialoge sind ein Musterbeispiel für Unübersichtlichkeit, außerdem sind die deutschen Texte miserabel übersetzt. Das, was Sie letztlich akzeptieren müssen, lautet sinngemäß: CentOS haftet nicht, egal welche Probleme auch auftreten.

Versionsnummern

Die folgende Tabelle fasst die Versionsnummern der wichtigsten Komponenten von CentOS 7.2 zusammen.

Basis             Desktop             Programmierung   Server
---------------   ------------------  ---------------  ---------------
Kernel    3.10    Gnome        3.14   bash     4.2     Apache    2.4
glibc     2.17    KDE          4.10   gcc      4.8     CUPS      1.6
GRUB      2.0     Firefox      38     Java   6/7/8      MariaDB   5.5
Systemd   208     Gimp         2.8    PHP      5.4     qemu/KVM  1.5
X-Server  1.15    LibreOffice  4.3    Python   2.7     Postfix   2.10
                  Thunderbird  ---                     OpenSSH   6.6
                                                       Samba     4.2

Viele Versionsnummern sind im Vergleich zu CentOS 7.0 unverändert, aber es gibt einige bemerkenswerte Überraschungen:

  • Systemd: 208 –> 219
  • Gnome: 3.8 –> 3.14
  • LibreOffice: 4.1 –> 4.3
  • Samba: 4.1 –> 4.2

Mit anderen Worten: Der Desktop wurde aktualisiert (Gnome, LibreOffice, Firefox sowieso), was in RHEL 6 bzw. CentOS 6 nicht unüblich war. Unter Gnome ist nach wie vor der Classic-Desktop vorkonfiguriert. KDE-seitig gab es übrigens keine nennenswerten Updates.

Gleichzeitig ist PHP bei der vollkommen überholten Version 5.4 stehen geblieben, was für eine Server-Distribution doch etwas merkwürdig ist.

Fazit

Von den oben erwähnten Update-Problemen mal abgesehen, bleibe ich bei meiner schon mehrfach formulierten Überzeugung: RHEL/CentOS ist als Desktop-Distribution deutlich attraktiver als es allgemein wahrgenommen wird. Wer einen stabilen, nicht unbedingt vollkommen aktuellen Desktop will und keine Lust auf ständige Neuinstallationen hat, macht mit CentOS nichts verkehrt.

Im kommerziellen Server-Segment ist Red Hat Marktführer — da scheint allzuviel Kritik nicht angebracht. Ein Update auf PHP 5.6 fände ich aber dennoch wünschenswert ;-) Vielleicht in RHEL/CentOS 7.3?

Links

Xcode-Tipp: print-Ausgaben im Playground

$
0
0

Wenn Sie in Xcode in einem Swift-Playground print-Ausgaben durchführen, sind diese anfangs unsichtbar. Dieser Mini-Beitrag fasst zusammen, wie Sie die Ausgaben lesen können.

print-Ergebnisse im Playground anzeigen
print-Ergebnisse im Playground anzeigen
  • Allgemein bekannt ist, dass Sie über die Mini-Icons am rechten Rand das letzte print-Ergebnis einblenden können (Show Result). Diese Funktion wurde im vergangenen Jahr mehrfach verändert und ist bis heute nur mäßig hilfreich.

  • Oft wollen Sie nicht nur das letzte Ergebnis sehen, sondern durch alle Ausgaben scrollen — z.B. in Schleifen. Dazu öffnen Sie das Kontextmenü der grauen Ergebnisbox und führen das Kommando Value History aus.

  • Wenn Ausgaben in mehreren Teilen zusammengesetzt werden oder in verschiedenen Funktionen erfolgen, ist auch diese Value History nicht der Stein der Weisen: Zum einen geht darin die Chronologie der Ausgaben verloren, die an unterschiedlichen Orten im Code erfolgten. Zum anderen werden dabei mehrteilige Ausgaben (print(..., terminator="") getrennt. Abhilfe: Ziehen Sie den grauen Balken am unteren Ende des Xcode-Fensters nach oben. Darunter befinden sich — gut versteckt! — alle Ausgaben des Testprogramms. In vielen Fällen ist dies die hilfreichste Ansicht.

Raspbian auf eine 128-GByte-SD-Karte installieren

$
0
0

Offiziell unterstützt der Raspberry Pi nur den SDHC-Standard (bis 32 GByte), nicht aber den SDXC-Standard für SD-Karten mit mehr Speicher. Das heißt aber nicht, dass es unmöglich ist, derartige SD-Karten zu verwenden. Da ich gerade einen DLNA-Server auf einem Pi-Zero einzurichten möchte, habe ich versucht, Raspbian auf eine 128-GByte-SD-Karte zu installieren — und siehe da: Probleme haben (wieder einmal) nur die Benutzer, die aus der Windows-Welt kommen …

Hintergründe

Es gibt zwei Arten, Raspbian zu installieren:

  • NOOBS: Hier wird die SD-Karte FAT-formatiert, anschließend werden die NOOBS-Installationsdateien einfach auf die SD-Karte kopiert. Das ist anfängerfreundlich und auch unter Windows leicht zu bewerkstelligen.
  • Image: Bei dieser Variante wird das Raspbian-Image blockweise auf die SD-Karte kopiert — unter Linux üblicherweise mit dd. Das erfordert ein wenig technisches Wissen (richtiger Device-Name!) und setzt voraus, dass ein Windows- oder OS-X-Rechner zur Verfügung steht.

Die Image-Installation funktioniert unabhängig von der Größe der SD-Karte.

Probleme gibt es nur bei der NOOBS-Variante. Der SDXC-Standard sieht nämlich vor, dass auf SD-Karten mit mehr als 32 GByte ein exFAT-Dateisystem einzusetzen ist. An sich ist das durchaus vernünftig, nur: Der Boot-Vorgang des BCM2835/BCM2836-Chips setzt voraus, dass sich die Boot-Dateien auf der ersten Partition der SD-Karte in einem FAT-Dateisystem befinden. Mit anderen Worten: Der NOOBS-Bootvorgang scheitert, wenn große SD-Karten ein exFAT-Dateisystem verwenden.

Große SD-Karten FAT-formatieren

Nun denn, dann formatieren wir die SD-Karte eben mit einem FAT-Dateisystem, bevor wir die NOOBS-Dateien dorthin kopieren. Am einfachsten gelingt dies unter OS X: Im Festplattendienstprogramm wählen Sie Löschen und wählen dann MS-DOS-Dateisystem (FAT) aus.

Wenig Probleme gibt es auch unter Linux. Die folgenden Kommandos gelten unter der Annahme, dass /dev/sdc das Device der SD-Karte ist.

umount /dev/sdc*
parted /dev/sdc mklabel msdos
parted /dev/sdc 'mkpart primary fat32 1MiB -1MiB'
mkfs.vfat -F 32 /dev/sdc1

Einzig Windows muckt: Wenn Sie die SD-Karte im Explorer auswählen und zu formatieren versuchen, stehen nur die Dateisysteme NTFS und exFAT zur Wahl. Ebenso inflexibel ist das format-Kommando, das in cmd.exe ausgeführt werden kann. Auch keine Hilfe ist das offizielle Formatierungsprogramm der SD Association (Download-Link) — es hält sich konsequenterweise an den SDXC-Standard und verwendet ohne irgendwelche Einstelloptionen exFAT.

Erfolg hatte ich schließlich mit dem kostenlosen (GPL!) Programm guiformat.exe von Ridgecrop. KLicken Sie auf der guiformat-Seite einfach auf den Screenshot, um das winzige, in eine ZIP-Datei verpackte Programm hinunterzuladen.

FAT32-Formatierung auch für große SD-Karten
FAT32-Formatierung auch für große SD-Karten

NOOBS-Installation

Egal, unter welchem Betriebssystem Sie die SD-Karte formatiert haben: Die nachfolgende NOOBS-Installation verläuft vollkommen unkompliziert.

NOOBS-Installation
NOOBS-Installation

Während der Installation verkleinert das Installationsprogramm die FAT-Partition und richtet diverse neue Partitionen ein. Raspbian landet schließlich auf der 118 GByte großen Partition /dev/mmcblk0p6.

pi@test128:~ $ lsblk
NAME        MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
mmcblk0     179:0    0  119,1G  0 disk
  mmcblk0p1 179:1    0 1023,5M  0 part
  mmcblk0p2 179:2    0      1K  0 part
  mmcblk0p3 179:3    0     32M  0 part /media/pi/SETTINGS
  mmcblk0p5 179:5    0     63M  0 part /boot
  mmcblk0p6 179:6    0    118G  0 part /

pi@test128:~ $ df -h
Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
/dev/root       116G    3,3G  107G    3% /
devtmpfs        459M       0  459M    0% /dev
tmpfs           463M       0  463M    0% /dev/shm
tmpfs           463M     13M  451M    3% /run
tmpfs           5,0M    4,0K  5,0M    1% /run/lock
tmpfs           463M       0  463M    0% /sys/fs/cgroup
/dev/mmcblk0p5   63M     20M   44M   31% /boot
tmpfs            93M       0   93M    0% /run/user/1000
/dev/mmcblk0p3   27M    1,6M   24M    7% /media/pi/SETTINGS

Kurzfassung

Alle, die Raspbian oder andere Pi-Betriebssysteme als Image-Datei auf eine SD-Karte kopieren, können große SDXC-Karten wie herkömmliche SDHC-Karten verwenden.

NOOBS-Freunde müssen den Datenträger zuerst mit einem FAT32-Dateisystem formatieren. Unter OS X und Linux gelingt das mit Bordmitteln, nur unter Windows ist ein spezielles Formatierprogramm erforderlich (z.B. guiformat).

Einschränkungen

Es gibt im Internet diverse Berichte, dass die Installation auf sehr großen SD-Karten gescheitert ist. Ich habe meine Tests nur mit einer einzigen SD-Karte durchgeführt, und zwar mit diesem Sandisk-Modell. Ich sehe zwar keinen Grund, warum es nicht mit anderen SD-Karten ebenso funktioniert, aber versprechen kann ich natürlich nichts. Werfen Sie gegebenenfalls einen Blick auf die folgende Seite, wo einige offensichtlich inkompatible Modelle aufgelistet werden.

http://elinux.org/RPi_SD_cards


Raspbian Lite für den Read-Only-Betrieb konfigurieren

$
0
0

Raspbian Lite ist eine Raspbian-Variante ohne Grafiksystem und GUI-Programme, ohne Java und Mathematica. Sie eignet sich daher besonders gut für Anwendungen, bei denen ein Raspberry Pi ohne Monitor Steuerungs- oder Server-Aufgaben übernehmen soll.

Wenn es für die Anwendung keine Notwendigkeit gibt, Daten auf der SD-Karte zu verändern, kann Raspbian Lite mit geringem Aufwand in ein Read-Only-System umgewandelt werden. Das hat den Vorteil, dass eine Beschädigung des Dateisystems nahezu ausgeschlossen ist, wenn der Raspberry Pi ohne einen richtigen Shutdown ausgeschaltet wird (sprich: wenn einfach der Stecker gezogen wird).

Ausgangspunkt für diese Anleitung ist ein fertig installiertes und konfiguriertes Raspbian Jessie Lite System. Bei meinem Testsystem ist der einzige USB-Port mit einem WLAN-Stecker verbunden. Der Minirechner bezieht über das WLAN seine Netzwerkdaten (mit DHCP). Das System kann also via SSH gesteuert werden.

Die minimale WLAN-Konfiguration in /etc/network/interfaces sieht so aus:

auto lo
iface lo inet loopback

auto wlan0
iface wlan0 inet dhcp
  wpa-ssid "meine-wlan-ssid"
  wpa-psk  "streng geheim"

Aufräumarbeiten

Nach einem Update entfernen Sie mit apt-get remove alle Pakete, die nicht mehr benötigt werden bzw. die ein Read-Write-Dateisystem unbedingt voraussetzen. Durch die folgenden Kommando wird auch raspi-config entfernt; wenn Sie das Tool für Konfigurationsarbeiten benötigen, sollten Sie diese vorher erledigen.

apt-get update && apt-get dist-upgrade
apt-get remove --purge cron logrotate triggerhappy dphys-swapfile fake-hwclock samba-common
apt-get autoremove --purge

Temporäre Dateisysteme im RAM

Ganz ohne Schreibzugriff geht es nicht. Deswegen werden die Verzeichnisse, die für Schreibzugriffe unbedingt erforderlich sind, in temporären Verzeichnisse verlagert, die im Arbeitsspeicher abgebildet werden. Beachten Sie, dass alle dort gespeicherte Daten bei jedem Reboot verloren gehen!

rm -rf /var/lib/dhcp/ /var/spool /var/lock
ln -s /tmp /var/lib/dhcp
ln -s /tmp /var/spool
ln -s /tmp /var/lock
ln -s /tmp/resolv.conf /etc/resolv.conf

/etc/fstab

In /etc/fstab sind zwei Änderungen erforderlich:

  • Zum einen für die Verzeichnisse / und /boot jeweils die Option ro, damit die Dateisysteme wirklich read-only in den Verzeichnisbaum eingebunden werden.
  • Und zum anderen drei neue Zeilen, um für /var/log, /var/tmp und /tmp jeweils ein temporäres Dateisystem einzurichten.

Die resultierende Datei sieht bei mir so aus:

# Datei /etc/fstab
proc            /proc           proc    defaults              0 0
/dev/mmcblk0p1  /boot           vfat    ro,defaults           0 2
/dev/mmcblk0p2  /               ext4    ro,defaults,noatime   0 1
tmpfs           /var/log        tmpfs   nodev,nosuid          0 0
tmpfs           /var/tmp        tmpfs   nodev,nosuid          0 0
tmpfs           /tmp            tmpfs   nodev,nosuid          0 0

Beachten Sie, dass die Device-Namen bei einer NOOBS-Installation anders aussehen.

/boot/cmdline

Auch /boot/cmdline muss verändert werden. Am Ende der langen Optionszeile fügen Sie die Optionen fastboot noswap hinzu. fastboot bedeutet, dass während des Bootvorgangs keine Überprüfung des Dateisystems erfolgen soll. noswap bedeutet, dass Linux ohne Swap-Datei arbeiten muss. Achten Sie darauf, dass Ihr Editor die Zeile nicht umbricht — alles muss in einer langen Zeile stehen.

Bei mir sieht diese Zeile so aus:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fastboot noswap

Test

Damit sind alle Vorbereitungsarbeiten abgeschlossen. Mit reboot sollte Ihr System nun im Read-Only-Modus starten. Davon können Sie sich mit mount und touch überzeugen.

mount | grep mmcblk
  /dev/mmcblk0p2 on / type ext4 (ro,noatime,data=ordered)
  /dev/mmcblk0p1 on /boot type vfat (ro,relatime,
     fmask=0022,dmask=0022,codepage=437,iocharset=ascii,
     shortname=mixed,errors=remount-ro)
touch xy
  touch: cannot touch ‘xy’: Read-only file system

Bei meinen Tests funktionierte anfänglich die WLAN-Konfiguration nicht, weil ich den Link von /etc/resolv.conf in ein temporäres Dateisystem vergessen und für /tmp kein temporäres Dateisystem eingerichtet hatte.

Für allfällige Korrekturmaßnahmen ist es erforderlich, dass Sie Ihren Minicomputer an einen Monitor anschließen und über eine Tastatur bedienen können.

Boot-Geschwindigkeit und Platzbedarf

Mein Testkandidat war ein Raspberry Pi Zero. Vom Anstecken bis zum Start des SSH-Servers vergehen rund 21 Sekunden. Das ist nicht traumhaft schnell, sollte aber für die meisten Anwendungsfälle ausreichen.

Der Platzbedarf für das gesamte System beträgt rund 1 GByte. Für die Installation von Raspbian Lite benötigen Sie eine SD-Karte mit zumindest 2 GByte.

df -h
  Filesystem      Size  Used Avail Use% Mounted on
  /dev/root       1.3G  945M  247M  80% /
  devtmpfs        214M     0  214M   0% /dev
  tmpfs           218M     0  218M   0% /dev/shm
  tmpfs           218M  8.4M  209M   4% /run
  tmpfs           5.0M     0  5.0M   0% /run/lock
  tmpfs           218M     0  218M   0% /sys/fs/cgroup
  tmpfs           218M  8.0K  218M   1% /tmp
  tmpfs           218M     0  218M   0% /var/tmp
  tmpfs           218M  132K  218M   1% /var/log
  /dev/mmcblk0p1   60M   20M   41M  34% /boot

free -h
             total       used       free     shared    buffers     cached
Mem:          434M        77M       357M       8.5M       6.3M        40M
-/+ buffers/cache:        30M       403M
Swap:           0B         0B         0B

Leisungsaufnahme

Die Leistungsaufnahme für den Pi Zero samt USB-WLAN-Stecker beträgt laut diesem simplen USB-Messgerät im Leerlauf rund 0,7 bis 0,8 Watt. Unter Last (CPU plus Netzwerk-Transfers) steigt der Verbrauch auf ca. 1,1 Watt.

Änderungen durchführen

Wenn Sie später doch einmal Änderungen durchführen möchten, loggen Sie sich ein und führen

mount -o remount,rw /

bzw. für das Boot-Verzeichnis

mount -o remount,rw /boot

aus. Damit kann das Dateisystem nun bis zum nächsten Reboot verändert werden.

Quellen

Der Raspberry Pi als DLNA-Server

$
0
0

DLNA steht für Digital Living Network Alliance (Wikipedia). Die in dieser Gruppe vereinten Hersteller von Unterhaltungselektronik haben sich auf diverse Standards geeinigt. So können DLNA-konforme Geräte beispielsweise unkompliziert im lokalen Netzwerk verfügbare Mediendateien (Bilder, Musik, Videos) anzeigen oder abspielen. Dieser Beitrag zeigt, wie Sie mit minimalem Aufwand aus einem Linux-Rechner einen DLNA-tauglichen Digital Media Server (DMS) machen.

Ausgangspunkt für die Anleitung ist ein Raspberry Pi mit installiertem Raspbian Jessie und einer Verbindung in das lokale Netzwerk. Ich habe meine Tests mit einem Pi Zero durchgeführt, der über einen USB-WLAN-Adapter mit meinem WLAN zuhause verbunden ist. Die Medien-Dateien — in meinem Fall ausschließlich Audio-Dateien — befinden sich direkt auf der SD-Karte.

ReadyMedia/MiniDLNA

Der vermutlich am einfachsten zu konfigurierende DLNA-Server für Linux heißt ReadyMedia (ehemals MiniDLNA). Unter Raspbian installieren Sie das Programm einfach mit

apt-get install minidlna

Die Konfiguration erfolgt durch die Datei /etc/minidlna.conf. Mit der Ausnahme weniger Einstellungen können Sie alle Voreinstellungen belassen. Das folgende Listing fasst nur die Zeilen zusammen, die Sie üblicherweise hinzufügen bzw. ändern müssen:

# Datei /etc/minidlna.conf
...
# Audio-, Video- und Picture-Verzeichnisse angeben
media_dir=A,/mymedia/musik
media_dir=A,/mymedia/hoerbuecher
media_dir=V,/mymedia/filme
media_dir=P,/mymedia/fotos1
media_dir=P,/mymedia/fotos2

# Name, der auf DLNA-Geräten angezeigt wird
friendly_name=MyMediaServer

# Änderungen in der Medienbibliothek selbstständig erkennen
# mit no muss nach dem Hinzufügen neuer Mediendateien
#   service minidlna restart
# ausgeführt werden
inotify=yes

Damit die Änderungen wirksam werden, starten Sie den DLNA-Server neu:

service minidlna restart

Cache-Verzeichnis

Falls der DLNA-Server auf einem Read-Only-System laufen soll (dann natürlich mit inotify=no), ist noch ein Problem zu lösen: ReadyMedia alias MiniDLNA legt standardmäßig im Verzeichnis /var/cache/minidlna eine Datenbank für alle Mediendateien sowie für die Cover-Bilder von MP3-Tracks an. Dazu muss das Programm in diesem Programm natürlich Schreibrechte haben.

Es gibt dafür zwei Lösungsansätze:

  • Sie sehen ein Temporäres Dateisystem für /var/cache/minidlna vor.
  • Sie platzieren das Cache-Verzeichnis im Dateisystem für die Mediendateien und lassen den DLNA-Server nach jedem Update der Mediendateien zumindest einige Minute im rw-Modus laufen, damit die Datenbank aktualisert wird.

Im Folgenden stelle ich beide Varianten etwas näher vor.

Cache im temporären Dateisystem

service minidlna stop
mount -o remount,rw /
rm -rf /var/cache/minidlna/*

Jetzt fügen Sie in /etc/fstab die folgende Zeile hinzu:

# Datei /etc/fstab
...
tmpfs   /var/cache/minidlna     tmpfs   nodev,nosuid    0       0

Zuletzt starten Sie Ihren Minirechner mit reboot neu. Nach dem Neustart dauert es nun je nach Größe der Mediathek etliche Minuten, bis minidlna über eine komplette Datenbank aller Titel verfügt. Der Platzbedarf für das temporäre Dateisystem im RAM ist überschaubar. Bei meinen rund 30 GByte Musikdateien beansprucht das Cache-Dateisystem ca. 25 MByte.

Cache-Verzeichnis im Medien-Dateisystem

Im Folgenden gehe ich davon aus, das im Verzeichnis /mymedia ein Dateisystem für die Mediendateien eingebunden ist. In diesem Dateisystem soll nun auch das Cache-Verzeichnis eingerichtet werden. (Alle weiteren Kommandos sind mit sudo auszuführen.)

service minidlna stop
mount -o remount,rw /
mount -o remount,rw /mymedia
rm -rf /var/cache/minidlna
mkdir /mymedia/cache
chown minidlna.minidlna /mymedia/cache
ln -s /mymedia/cache /var/cache/minidlna
service minidlna start

Jetzt beobachten Sie mit top den Prozess minidlna. Er wird für einige Minuten mit hoher CPU-Belastung das gesamte Medienarchiv durchforsten und die Datenbank einrichten. (Bei mir dauert das für 30 GByte Musikdateien rund vier Minuten — also etwas mehr als eine Minute pro 10 GByte Mediendateien.) Wenn minidlna von den vorderen Rängen der top-Liste verschwindet, ist die Medien-Datenbank aktuell. Jetzt können Sie das System neu im Read-Only-Modus starten.

Wenn Sie in Zukunft Mediendateien hinzufügen, führen Sie neuerlich mount -o remount,rw /mymedia aus und geben minidlna dann einige Minuten Zeit, um seine Datenbank zu aktualisieren. Anschließend können Sie das System wieder in den Read-Only-Modus rebooten.

Der Vorteil dieser Vorgehensweise besteht darin, dass minidlna nach einem Neustart sofort Zugriff auf die fertige Mediendatenbank hat.

Praxis

Bei mir zuhause läuft MiniDLNA auf einem Pi Zero mit einer 128-GByte-SD-Karte und in Read-Only-Konfiguration. Die Medien-Dateien befinden sich in einem eigenen Dateisystem (auch Read-Only, außer wenn ich per SSH neue Mediendateien hinzufüge). Das Cache-Verzeichnis habe ich ebendort eingerichtet (gemäß der zweiten Cache-Konfigurationsvariante von oben).

Den Pi-Zero habe ich an die Rückseite des Netzwerk-Lautsprecher Sony SRS-X77 geklebt. Der Minicomputer bezieht seine Stromversorgung von der USB-Buchse des Geräts, die eigentlich zum Laden von Smartphones gedacht ist. Sehr praktisch :-)

Der Pi Zero ist auf die Rückwand eines Sony-Netzwerklautsprechers geklebt
Der Pi Zero ist auf die Rückwand eines Sony-Netzwerklautsprechers geklebt

Jedes Smartphone/Tablet im Haushalt, auf das/dem eine DLNA-Player-App installiert ist, kann nun Musik aus der DLNA-Bibliothek auswählen und wahlweise direkt auf dem Smartphone/Tablet oder aber via Bluetooth/AirPlay/Google Cast auf dem Funklautsprecher abspielen.

Jetzt stört nur noch die hohe Stand-by-Leistungsaufnahme des Geräts (ca. 5 Watt). Da es — wie bei modernen Geräten leider üblich — keinen richtigen Ein/Aus-Schalter gibt, werde ich das Netzkabel des Geräts mit einem Schalter versehen. Damit wird dann aber auch die Stromversorgung des Raspberry Pi im laufenden Betrieb gekappt. Dank der Read-Only-Konfiguration sind dabei glücklicherweise keine Datenverluste zu erwarten.

Quellen

On-Board-LEDs des Raspberry Pi steuern

$
0
0

Es gibt sicher 1000 Anleitungen, wie Sie eine Leuchtdiode über einen Vorwiderstand mit einem GPIO-Pin verbinden und diese dann per Python, bash oder in sonst einer Programmiersprache ein- und wieder ausschalten. Aber wussten Sie, dass Sie auch die im Raspberry Pi integrierten LEDs per Software ein- und ausschalten können?

Im Folgenden beziehe ich mich auf den Raspberry Pi 2, Modell B. Bei diesem Modell gibt es vier LEDs. Zwei sind in die Ethernet-Buchse integriert und nicht Thema dieses Beitrags. Die beiden anderen befinden sich am Beginn der GPIO-Leiste:

  • Die grüne LED (Status-LED = led0) flackert üblicherweise, wenn Daten von/zur SD-Karte übertragen werden.
  • Die rote LED (Power-LED = led1) zeigt an, dass der Raspberry Pi mit der Stromversorgung verbunden ist.

Das Verhalten dieser beider LED wird durch /sys/class/leds/led<n>/trigger bestimmt. Standardmäßig gelten die folgenden Einstellungen:

cat /sys/class/leds/led0/trigger
  none [mmc0] timer oneshot heartbeat backlight
  gpio cpu0 cpu1 cpu2 cpu3 default-on input
cat /sys/class/leds/led1/trigger
  none mmc0 timer oneshot heartbeat backlight
  gpio cpu0 cpu1 cpu2 cpu3 default-on [input]

Indem Sie beide trigger-Dateien mit none überschreiben, können Sie selbst die Kontrolle über die LEDs übernehmen:

sudo echo none > /sys/class/leds/led0/trigger
sudo echo none > /sys/class/leds/led1/trigger

Um eine LED ein- bzw. aus zu schalten, schreiben Sie 1 bzw. 0 in /sys/class/leds/led1/brightness:

sudo echo 0 > /sys/class/leds/led0/brightness  # grüne LED aus
sudo echo 1 > /sys/class/leds/led1/brightness  # rote LED ein

Vorausgesetzt, dass die trigger auf none steht, können Sie die LEDs auch mit GPIO-Kommandos steuern. Der grünen LED ist der GPIO 47 zugeordnet (in BCM-Nummerierung), der roten LED 35. Mit dem Wiring-Pi-Kommando gpio können Sie die LEDs auch ohne sudo ein- und ausschalten:

gpio -g  write 47 1  # grüne LED ein
gpio -g  write 47 0
gpio -g  write 35 1  # rote LED ein
gpio -g  write 35 0

Quellen:

VNC-Server mit Systemd starten

$
0
0

Vor einiger Zeit habe ich eine recht umfangreiche Anleitung zusammengestellt, wie man auf einem Raspberry Pi einen VCN-Server einrichtet. Diese Anleitung trifft zum größten Teil weiterhin zu. Da Raspbian Jessie nun aber Systemd als Init-System verwendet, liegt es nahe, den automatischen Start des VNC-Servers mittels Systemd zu konfigurieren.

Voraussetzungen

Zuerst installieren Sie den VNC-Server und probieren diesen aus, in dem Sie ihn manuell starten:

sudo apt-get install tightvncserver
vncserver
  Password: ******
  Verify:   ******
  Would you like to enter a view-only password? n
  New 'X' desktop is raspberrypi:1

Das beim ersten Start angegebene VNC-Passwort wird in der Datei .vnc/passwd in verschlüsselter Form gespeichert.

vncserver.service-Datei einrichten

Damit Systemd den VNC-Server starten kann, müssen Sie die service-Datei /etc/systemd/system/vncserver.service einrichten. Diese muss den folgenden Inhalt haben:

# neue Datei /etc/systemd/system/vncserver.service
[Unit]
Description=Remote desktop service (VNC)
After=syslog.target network.target

[Service]
Type=forking
User=pi
PAMName=login
PIDFile=/home/pi/.vnc/%H:1.pid
ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill :1 > /dev/null 2>&1 || :'
ExecStart=/usr/bin/vncserver -geometry 1300x800  -depth 16 :1
ExecStop=/usr/bin/vncserver -kill :1

[Install]
WantedBy=multi-user.target

Zum Ausprobieren führen Sie dieses Kommando aus:

sudo systemctl daemon-reload && systemctl start vncserver
systemctl status vncserver
  vncserver.service - Remote desktop service (VNC)
   Loaded: loaded (/etc/systemd/system/vncserver.service; disabled)
   Active: active (running) since Fre 2016-01-29 21:09:32 CET; 10min ago
   Main PID: 14430 (Xtightvnc)
  Jän 29 21:09:30 pi2 systemd[14397]:
    pam_exec(login:session): conversation failed
  Jän 29 21:09:30 pi2 systemd[14397]: pam_unix(login:session):
    session opened for user pi by (uid=0)
  ...

Ich habe leider keinen Weg gefunden, die pam_exec-Fehlermeldung zu vermeiden. Sie scheint aber keine Auswirkung auf den erfolgreichen Start des VNC-Servers zu haben.

Um den VCN-Server wieder zu stoppen, führen Sie systemctl stop aus:

sudo systemctl stop vncserver

Wenn Sie möchten, dass der VNC-Server von nun an beim Rechnerstart automatisch aktiviert wird, führen Sie noch dieses Kommando aus:

sudo systemctl enable vncserver

Sonstige Konfigurationsdateien

Prinzipiell sollte der automatische Start des VNC-Servers nun funktionieren. Zwei Kleinigkeiten stören aber:

  • Solange sich der Mauscursor nicht über einem Fenster befindet, wird dieser als hässliches X-Symbol dargestellt.
  • In neuen Terminal-Fenstern ist / das aktive Verzeichnis, nicht /home/pi.

Die beiden Probleme lassen sich mit wenig Mühe beheben. Zuerst laden Sie die Datei /home/pi/.vnc/xstartup in einen Editor und ergänzen die bereits vorhandene Anweisung xsetroot -solid grey um -cursor_name left_ptr.

# in /home/pi/.vnc/xstartup
xsetroot -solid grey -cursor_name left_ptr
...

Anschließend laden Sie /home/pi/.bashrc und fügen am Ende der Datei die Anweisung cd $HOME ein:

# am Ende von /home/pi/.bashrc
...
cd $HOME

Quellen

Neuauflage der Linux-Kommandoreferenz

$
0
0

2010 habe ich mich dazu entschieden, damals noch in Abstimmung mit dem Addison-Wesley-Verlag, die Kommandoreferenz aus meinem Linux-Schmöcker herauszulösen und zu einem eigenen Buch zu machen. Das hat (glaube ich) beiden Büchern gut getan:

  • In meinem »klassischen« Linux-Buch wurde Platz für neue Themen frei. Das Buch hat seither wesentlich mehr Tiefgang im Server-Bereich.
  • Und die Kommandoreferenz konnte — ebenfalls ohne große Platzprobleme — konsequent als Referenz konzipiert werden.

linux-kommandoreferenz2

Soeben ist die dritte Auflage der Linux-Kommandoreferenz erschienen: Der Umfang des Buchs ist mittlerweile auf 467 Seiten angewachsen. Da die fast 500 beschriebenen Kommandos alphabetisch angeordnet sind, sollte deren Suche aber unverändert rasch vor sich gehen. Neben diversen Aktualisierungen geht die Neuauflage insbesondere auf Systemd und Journal, die Dateisysteme btrfs und xfs sowie auf Kommandos aus dem Umfeld des Raspberry Pi stärker ein.

eBook inklusive

Als besonderes Highlight enthält das gedruckte Buch nun auch eine CD mit dem eBook (PDF). Mit vielen anklickbaren Querverweisen und einem gut organisierten PDF-Inhaltsverzeichnis ist jedes Kommando mit wenigen Maus- oder Trackpad-Klicks erreichbar.

eBook-Ausgabe der Kommandoreferenz im PDF-Viewer »Evince«
eBook-Ausgabe der Kommandoreferenz im PDF-Viewer »Evince«

Bluetooth-Konfiguration im Terminal mit bluetoothctl

$
0
0

In den letzten Tagen habe ich mich recht intensiv mit der Bluetooth-Konfiguration unter Raspbian Jessie auseinandergesetzt. Zur grafischen Konfiguration ist der Bluetooth-Manager vorgesehen (apt-get install bluetooth blueman), der mich aber in der Vergangenheit schon nicht glücklich gemacht hat und mit dem es mir auch diesmal nicht geglückt ist, zwei Bluetooth-Tastaturen einzurichten.

Wohl oder übel habe ich nun versucht, die Konfiguration auf Kommandoebene durchzuführen. Das von Raspbian Wheezy bekannte Werkzeug bluez-simple-agent steht unter Jessie nicht mehr zur Verfügung. Und so kam es, dass ich mit mit dem Kommando bluetoothctl angefreundet habe und damit eine Maus, zwei Tastaturen und einen Bluetooth-Lautsprecher mit dem Raspberry Pi verbunden habe.

bluetoothctl-Kommando

bluetoothctl ist zur interaktiven Konfiguration gedacht. Nach dem Start gelangen Sie in einen Kommandomodus. Die weitere Vorgehensweise zur Verbindung eines Bluetooth-Geräts sieht so aus:

  • Sie aktivieren mit pairable on den Kuppelungsmodus.
  • Sie aktivieren mit scan on den Scan-Modus. Das Programm listet nun alle erkannten Geräte in Funkreichweite auf. Dieser Vorgang kann geraume Zeit dauern, einzelne Geräte werden dabei immer wieder aufgelistet. Wenn Sie das gewünschte Gerät gefunden haben, schalten Sie den Modus mit scan off einfach wieder aus.
  • Sie aktivieren mit agent on einen sogenannten Bluetooth-Agenten. Er kümmert sich um die Autorisierung neuer Geräte (bei Tastaturen: Passworteingabe).
  • Mit pair xx:xx:xx initiieren Sie den Verbindungsaufbau zu einem Gerät. Bei einer Tastatur werden Sie nun dazu aufgefordert, einen sechstelligen Code einzutippen. Vergessen Sie nicht, die Eingabe mit Return abzuschließen! Die erfolgreiche Kuppelung erkennen Sie an der Meldung pairing successful. Bei Geräten ohne Eingabemöglichkeit (Tastatur, Lautsprecher etc.) gelingt das Pairing zum Glück auch ohne Codeeingabe.
  • Und mit trust xx:xx:xx machen Sie dem Bluetooth-System klar, dass Sie dem Gerät wirklich vertrauen.
  • Mit connect xx:xx:xx geben Sie an, dass Sie das Gerät tatsächlich nutzen möchten. (Das hätte sich bluetoothctl mittlerweile eigentlich denken können …) Wenn alles klappt, lautet die Reaktion connection successful. Das Gerät kann jetzt verwendet werden!
  • info xx:xx:xx zeigt den Verbindungsstatus und diverse weitere Informationen zum Gerät an.
  • Bei der Fehlersuche helfen die Kommandos list und devices.* Mit exit beenden Sie das bluetoothctl-Kommando.

Wichtig ist, dass Sie bei neu zu konfigurierenden Bluetooth-Geräten immer wieder auf den Bluetooth-Knopf (Pairing-Knopf) drücken, damit das Gerät so der Umwelt signalisiert, dass es bereits zum Verbindungsaufbau ist. Die meisten Geräte signalisieren diesen Zustand auch durch eine blinkende Leuchtdiode.

bluetoothctl-Beispiel

Die folgenden Zeilen zeigen (leicht gekürzt) die Ein- und Ausgaben zur Konfiguration einer Bluetooth-Tastatur. Alle Ein- und Ausgaben erfolgen in einem Terminal-Fenster:

pi@pi2$ bluetoothctl
[NEW] Controller 00:1A:7D:DA:71:13 pi2 [default]
[NEW] Device 88:E7:A6:04:9E:A7 Bluetooth Laser Mouse
[NEW] Device 00:25:BC:FB:C1:E5 Michael Koflers Tastatur

[bluetooth]# agent on
Agent registered

[bluetooth]# pairable on
Changing pairable on succeeded

[bluetooth]# scan on
Discovery started
[CHG] Controller 00:1A:7D:DA:71:13 Discovering: yes
[NEW] Device 70:10:00:1A:92:20 70-10-00-1A-92-20
[NEW] Device 73:0C:0F:CF:F3:BE 73-0C-0F-CF-F3-BE
[CHG] Device 70:10:00:1A:92:20 LegacyPairing: no
[CHG] Device 70:10:00:1A:92:20 Name: Bluetooth 3.0 Keyboard
[CHG] Device 70:10:00:1A:92:20 Alias: Bluetooth 3.0 Keyboard
[CHG] Device 70:10:00:1A:92:20 LegacyPairing: yes
...

bluetooth]# scan off
Discovery stopped

[bluetooth]# pair 70:10:00:1A:92:20
Attempting to pair with 70:10:00:1A:92:20
[CHG] Device 70:10:00:1A:92:20 Connected: yes
[agent] PIN code: 963064

  --> Pin-Eingabe + Return auf der Tastatur <--

[CHG] Device 70:10:00:1A:92:20 Paired: yes
Pairing successful

[bluetooth]# trust 70:10:00:1A:92:20
Changing 70:10:00:1A:92:20 trust succeeded
[CHG] Device 88:E7:A6:04:9E:A7 Connected: yes

[bluetooth]# connect 70:10:00:1A:92:20
Attempting to connect to 70:10:00:1A:92:20
Connection successful

[bluetooth]# info 70:10:00:1A:92:20
Device 70:10:00:1A:92:20
    Name: Bluetooth 3.0 Keyboard
    Alias: Bluetooth 3.0 Keyboard
    Class: 0x000540
    Icon: input-keyboard
    Paired: yes
    Trusted: yes
    Blocked: no
    Connected: yes
    LegacyPairing: no
    UUID: Service Discovery Serve.. (00001000-...)
    UUID: Human Interface Device... (00001124-...)
    UUID: PnP Information           (00001200-...)
    Modalias: usb:v04E8p7021d0001

[bluetooth]# exit

Test, Interna

Wenn soweit alles klappt, sollten Sie nun einen Neustart durchführen. Auf diese Weise stellen Sie sicher, dass die Konfiguration tatsächlich gespeichert wurde und nachhaltig funktioniert.

Die Bluetooth-Konfiguration für ein bestimmtes Gerät wird in /var/lib/bluetooth/id1/id2/info gespeichert. Dabei ist id1 der ID-Code des Bluetooth-Controllers (beim Raspberry Pi also eines USB-Bluetooth-Steckers) und id2 der ID-Code des Bluetooth-Geräts.

sudo less /var/lib/bluetooth/controller-id/device-id/info
[LinkKey]
Key=44763CF7C981D575C28BC05C90184F00
Type=0
PINLength=0

[General]
Name=Bluetooth 3.0 Keyboard
Class=0x000540
SupportedTechnologies=BR/EDR;
Trusted=true
Blocked=false
Services=00001000-0000-1000-8000-00805f9b34fb;00001124-0000-1000-8000-00805f9b34fb;00001200-0000-1000-8000-00805f9b34fb;

[DeviceID]
Source=2
Vendor=1256
Product=28705
Version=1

Bluetooth-Lautsprecher für den Raspberry Pi

Quasi als Anwendungsbeispiel habe ich nun versucht, einen Bluetooth-Lautsprecher zu verwenden, um mit dem LXMusic abgespielte MP3-Dateien wiederzugeben. Zuerst einmal müssen Sie die erforderlichen Bibliotheken für die Kommunikation zwischen Bluetooth und dem Audio-System installieren:

sudo apt-get install pulseaudio-module-bluetooth

Der nächste Schritt besteht darin, den Lautsprecher mit dem Raspberry Pi zu verbinden — wahlweise wie oben beschrieben mit bluetoothctl oder mit dem Bluetooth Manager. Sobald das gelungen ist, sollte das Kommando pactl list neben dem internen Audio-Ausgang des Raspberry Pi auch den Bluetooth-Lautsprecher anzeigen:

pactl list sinks short
  0 alsa_output.0.analog-stereo   module-alsa-card.c      ... RUNNING
  1 bluez_sink.FC_58_FA_A0_4D_E7  module-bluez5-device.c  ... SUSPENDED

Ebenfalls mit pactl machen Sie nun den Bluetooth-Lautsprecher zum Default-Audio-Ausgang und stellen die gewünschte Lautstärke ein.

pactl set-default-sink 1
pactl set-sink-volume 1 60%

Wenn Sie jetzt mit einem Audio-Player Musik abspielen, also z.B. mit ‚LXMusic‘, sollte die Tonausgabe aus der Bluetooth-Box erschallen.

Leider geht die Verbindung mit jedem Neustart des Raspberry Pi verloren. Sie müssen wahlweise im Bluetooth Manager das Connect-Kommando ausführen oder mit bluetoothctl die Verbindung wiederherstellen. In einem Script kann das z.B. so erfolgen (wobei Sie natürlich die ID-Nummer ändern müssen):

echo -e "connect FC:58:FA:A0:4D:E7\nquit" | bluetoothctl

Lästig ist, dass die unter Raspbian zugänglichen Lautstärkeregler keinen Einfluss auf die Bluetooth-Lautstärke haben. Die Lautstärke kann einerseits auf der Box selbst und andererseits mit pactl verändert werden, z.B. so:

pactl set-sink-volume bluez_sink.FC_58_FA_A0_4D_E7 50%

Beachten Sie, dass die beiden Lautstärken sich multiplizieren: Die pactl-Lautstärke gibt an, in welcher Lautstärke die Daten per Bluetooth übertragen werden. Die Lautstärke der Box verstärkt dieses Signal dann nochmals.

Ein ärgerliches Verhalten meines Testkandidaten (Anker A7908) bestand darin, dass das Gerät nach jedem Aus- und Einschalten die interne Lautstärke auf 100% zurücksetzt.

Restlos begeistert hat mich die Kombination aus dem Raspberry Pi mit dem Anker-Lautsprecher also nicht. Aber immerhin hat sich gezeigt, dass eine Audio-Wiedergabe per Bluetooth grundsätzlich möglich ist und dass es keine unüberwindbaren Hürden gibt.

Quellen

Wie ich ein QCOW2-Image auf ein Drittel geschrumpft habe

$
0
0

Ich verwende auf meinem Root-Server KVM zur Virtualisierung. In einer der virtuellen Maschinen läuft meine Website https://kofler.info. Die virtuelle Festplatte dieser VM befindet sich in einer QCOW2-Image-Datei. Diese ist im Laufe der Jahre auf rund 30 GiB angewachsen (bzw. rund 32 GB bei dezimaler Rechnung). Tatsächlich beträgt die Virtual Size aber nur 24 GB (dezimal), und davon sind innerhalb der Maschine wiederum nur zwei Drittel genutzt. Da müsste es doch möglich sein, die QCOW2-Datei auzuräumen, oder?

Image-Datei aufräumen (von »außen«)

Die folgenden Kommandos wurden am Host ausgeführt, vorerst mit einer Backup-Datei des Images, um den laufenden Betrieb nicht zu stören:

qemu-img info ausgangspunkt.qcow2
  image: ausgangspunkt.qcow2
  file format: qcow2
  virtual size: 24G (25769803776 bytes)
  disk size: 32G
  cluster_size: 65536
  Format specific information:
      compat: 0.10
      refcount bits: 16

Die Image-Datei ist also ca. 32 GiB groß, obwohl die Nutzdaten maximal ca. 24 GiB betragen. Wie kann das sein? Der Overhead resultiert einerseits aus (vielfach nicht mehr benötigten Meta-)Daten der QCOW2-Datei, andererseits aus nicht mehr vorhandenen Snapshots, die im Laufe der Zeit erzeugt und wieder entfernt wurden. Mit qemu-img convert können diese nicht mehr benötigten Ramsch-Daten entfernt werden. (Das Image darf dabei nicht in Betrieb sein!!)

qemu-img convert ausgangspunkt.qcow2  -O qcow2 aufgeraeumt.qcow2

Optional können Sie bei qemu-img convert die Option -c verwenden. Dann werden die Datenblöcke der Image-Datei zlib-komprimiert. Das dauert ziemlich lange (mehrere Minuten).

qemu-img convert ausgangspunkt.qcow2  -O qcow2 komprimiert.qcow2

Das Ergebnis (in binären MiB):

du -m *.qcow2
  30003  ausgangspunkt.qcow2
  23215  aufgeraeumt.qcow2
  13722  komprimiert.qcow2

Das ist ja schon eine ordentliche Verbesserung!

Dateisystem aufräumen (von »innen«)

Ein Blick in die virtuelle Maschine hinein zeigt, dass von den 24 GiB Image-Größe 23 für das Root-Dateisystem vorgesehen sind, das verbleibende GiB für die Swap-Partition. Das Root-Dateisystem nutzt aber nur ca. zwei Drittel des Speicherplatzes:

df -h
  /dev/vda1        23G     15G  7,4G   66% /

Das Problem ist, dass auch die ungenützten Speicherblöcke des Dateisystems alte, nicht mehr benötigte Daten enthalten. Nur wenn die ungenützten Speicherblöcke mit Nullen vollgeschrieben werden, kann das QCOW2-Image diese nun wirklich leeren Speicherblöcke aus dem Image entfernen. Der einfachste Weg, das zu bewerkstelligen, bietet das dd-Kommando. Damit können Sie eine riesige Datei aus Nullen erzeugen. Danach synchronisieren Sie das Dateisystem und löschen die Datei wieder. Laut df hat sich durch die Aktion nichts geändert.

dd if=/dev/zero of=zero bs=1M count=6500
sync
rm zero
df -h
  /dev/vda1        23G     15G  7,4G   66% /

Tipp: Vermeiden Sie es, mit dd das gesamte Dateisystem vollzuschreiben! Das führt zu einer starken Fragmentierung, die nicht wünschenswert ist.

Image-Datei nochmals aufräumen (von »außen«)

Nach diesen Vorarbeiten ist es an der Zeit, die VM für ein paar Minuten hinunterzufahren. Mit qemu-img convert kann nun eine neue, minimierte Image-Datei erzeugt werden:

mv kofler.info.qcow2 backup.qcow2
qemu-img convert backup.qcow2  -O qcow2 kofler.info.qcow2
du -m kofler.info.qcow2
  9796   kofler.info.qcow2

Damit ist die Image-Datei auf ein Drittel ihrer ursprünglichen Größe geschrumpft. Die VM kann nun wieder gestartet werden.

Nebenwirkungen

Die hier beschriebene Vorgehensweise hat zwei Nachteile:

  • Erstens ist die Ersparnis in diesem Umfang nicht von Dauer. Innerhalb der virtuellen Maschine werden neue ungenützte Speicherblöcke entstehen, selbst dann, wenn der Speicherbedarf des Dateisystems als Ganzes nicht steigt. Und auch im QCOW2-Image wird sich im Laufe der Zeit neuer ungenützter Speicher anhäufen. Damit die Ersparnis von Dauer ist, muss die hier skizzierte Aktion irgendwann (vielleicht in ein, zwei Jahren) wiederholt werden.

  • Zweitens hat die Komprimierung des Image (Option -c bei qemu-img convert) natürlich eine relativ hohe Auswirkung auf die Geschwindigkeit. Datenblöcke müssen beim Lesen dekomprimiert, beim Schreiben wieder komprimiert werden. Der Effekt ist bei schnellen Datenträgern (SSDs) deutlich stärker bemerkbar als bei langsamen Datenträgern (also herkömmlichen Festplatten). Ob Sie bereit sind, diesen Nachteil in Kauf zu nehmen, hängt von den Anforderungen ab. In meinem Fall läuft die VM kofler.info ohnedies die meiste Zeit im Leerlauf, der Geschwindigkeitsunterschied ist daher für mich nicht relevant. Gegebenenfalls lassen Sie die Option -c einfach weg, auch ohne die Komprimierung ist ja bereits eine deutliche Platzersparnis erreichbar.

Quellen


Der Raspberry Pi 3

$
0
0

Innerhalb von vier Jahren hat die Raspberry Pi Foundation nicht nur 8 Millionen Minicomputer verkauft, sondern auch eine ganze Reihe von Modellen präsentiert. Mit dem »Raspberry Pi 3 — Modell B« ist seit einigen Tagen der jüngste Spross der Raspberry-Pi-Familie verfügbar.

Rein äußerlich ist der Raspberry Pi 3 (Modell B) kaum von seinem Vorgängermodell zu unterscheiden.
Rein äußerlich ist der Raspberry Pi 3 (Modell B) kaum von seinem Vorgängermodell zu unterscheiden.

Die Modelle der Raspberry-Pi-Familie
Die Modelle der Raspberry-Pi-Familie

Eckdaten

  • 64-Bit-CPU BCM 2837 mit 1,2 GHz, ca. 50 bis 60% schneller als die CPU des Raspberry Pi 2
  • integriertes WLAN-Modul
  • integriertes Bluetooth-Modul
  • höherer Strombedarf (es wird ein 12 W-Netzteil empfohlen)

Unverändert:

  • Preis
  • 1 GByte RAM
  • Video-Core (aber etwas höhere Taktfrequenz)
  • 40 GPIOs (gleiches Layout)
  • HDMI-, Audio-, Ethernet- und USB-Anschlüsse
  • CSI/DSI-Anschlüsse für Kamera + Display

Geschwindigkeit und Overclocking

Die Geschwindigkeit des Pi 3 ist wirklich spürbar gestiegen. Ob die von der Raspberry Pi Foundation versprochenen 50 bis 60% Verbesserung im Vergleich zum Raspberry Pi 2 erreichbar sind, hängt aber vom jeweiligen Programm ab.

Wie beim Raspberry Pi Zero ist kein Overclocking vorgesehen. raspi-config sowie dessen grafische Variante lassen keine Veränderung der Taktfrequenz zu. Im Internet gibt es aber natürlich schon erste Berichte, dass ein Overclocking mit etwas Handarbeit dennoch gelingen kann:

http://www.jackenhack.com/raspberry-pi-3-overclocking

Empfehlenswert ist ein Overclocking aber definitiv nur, wenn Sie Ihren Raspberry Pi mit einem Kühlkörper ausstatten! Schon ohne Overclocking kann die CPU-Temperatur auf 80°C ansteigen.

Standardmäßig läuft der Pi 3 mit den folgenden Frequenzen:

               Pi 3, Modell B             Pi 2, Modell B
-------------------------------------------------------------
CPU-Takt:      600 MHz bis 1,2 GHz        600 MHz bis 900 MHz
RAM-Takt:      450 MHz                    450 MHz
Video Core IV: 400 MHz                    250 MHz
3D Core:       300 MHz                    250 MHz

So können Sie die Werte selbst ermitteln:

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
  600000
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
  1200000
vcgencmd get_config sdram_freq    # RAM
  sdram_freq=450
vcgencmd get_config core_freq     # Video Core
  core_freq=400
vcgencmd get_config gpu_freq      # 3D-Core
  gpu_freq=300

Stromverbrauch und Stromversorgung

Bei meinen Messungen mit einem einfachen USB-Meßgerät benötigte der Pi 3 im Leerlauf inklusive der Versorgung von Tastatur und Maus weniger als 2,5 W (4,97 V * 0,45 A). Das ist nicht mehr als beim Pi 2. Unter Last steigt die Leistungsaufnahme der CPU allerdings deutlich stärker als beim Pi 2. Bei meinen Messungen während eines sysbench-Durchlaufs verbrauchte der Pi 3 rund 5 W (4,97 V * 0,97 A).

sudo apt-get install sysbench
sysbench --test=cpu --cpu-max-prime=20000 --num-threads=4 run
  Test execution summary:
    total time:                          126.0253s
    total number of events:              10000
    total time taken by event execution: 504.0186
    per-request statistics:
         min:                                 47.69ms
         avg:                                 50.40ms
         max:                                 88.14ms
         approx.  95 percentile:              51.75ms
  Threads fairness:
    events (avg/stddev):           2500.0000/5.20
    execution time (avg/stddev):   126.0046/0.01

Die CPU-Temperatur stieg dabei auf 80°C (ohne Gehäuse, ohne Kühlkörper, Umgebungstemperatur 22°C). Alle CPU-Cores liefen während des über mehrere Minuten ausgeführten Tests mit 1,2 GHz.

cat /sys/class/thermal/thermal_zone0/temp
  80972
cat /sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq
  1200000
  1200000
  1200000
  1200000

Ich habe meine Tests mit demselben 5W-Netzteil (also 1A) durchgeführt, das in der Vergangenheit schon alle früheren Raspberry Pis mit Strom versorgt hat. Leistungsreserven für weitere USB-Geräte bietet dieses aber keine mehr.

Tipp: Wenn Sie derartige Tests durchführen, sollten Sie auf die rote Leuchtdiode des Pi 3 achten. Wenn diese gelegentlich blinkt, ist das ein Hinweis darauf, dass die Stromversorgung nicht ausreichend ist. Bei den Tests von golem.de hat sich gezeigt, dass auch ein schlechtes oder zu langes USB-Kabel zwischen Netzteil und Pi die Ursache für eine unzureichende Stromversorgung ist.

Die Empfehlung der Raspberry Pi Foundation, zur Stromversorgung ein 2,5-A-Netzteil zu verwenden, erscheint in jedem Fall übertrieben. Sie resultiert wohl eher daher, dass viele Billignetzteile nicht halten, was ihre Spezifikation verspricht — und dass daher ein leistungsstärkeres Netzteil weniger Probleme verspricht.

Wenn Sie über Ihren Raspberry Pi auch diverse USB-Geräte (z.B. Festplatten) mit Strom versorgen wollen, brauchen Sie definitiv ein stärkeres Netzteil. Diesbezüglich gibt es beim Pi 3 übrigens eine kleine Änderung im Vergleich zum Pi1/B+ bzw. Pi2/B: Der Parameter usb_max_current in config.txt wurde eliminiert. Der Pi 3 stellt USB-Geräten nun standardmäßig bis zu 1200 mA zur Verfügung. Beim Pi1/B+ bzw. Pi2/B war der Strom auf 600 mA beschränkt, außer config.txt enthielt usb_max_current=1. Auch diese Änderung mag ein Grund für die Empfehlung eines 2,5-A-Netzteils sein.

On-board-Leuchtdioden

Der Ort der auf dem Pi 3 integrierten Leuchtdioden hat sich geändert. Sie befinden sich nun direkt bei der Micro-USB-Buchse zur Stromversorgung.

Beachten Sie, dass beim Pi 3 nur mehr die grüne Leuchtdiode durch eigenen Code gesteuert werden kann (mehr Details hier):

sudo echo none > /sys/class/leds/led0/trigger
sudo echo 0 > /sys/class/leds/led0/brightness  # grüne LED aus
sudo echo 1 > /sys/class/leds/led0/brightness  # grüne LED ein

Wozu 64 Bit?

Das System-on-a-Chip BCM 2837 enthält eine 64-Bit-CPU mit ARMv8-Technologie. Das erscheint aus zweierlei Gründen sinnlos:

  • Zum einen beträgt der Arbeitsspeicher nur 1 GByte — und die lassen sich mit einem 32-Bit-Adressbus leicht adressieren. Mehr Speicher scheitert laut der Raspberry Pi Foundation an des Grafik-Core, und vor einem Wechsel des Grafik-Core schreckt man wegen Treiberproblemen zurück. (Anscheinend gibt es keinen geeigneten Core mit Open-Source-Treibern.)
  • Und zum anderen wird Raspbian nach wie vor in einem Image angeboten, das zu allen Raspberry Pis der Vergangenheit kompatibel ist. Anders formuliert: Raspbian ist für die ARMv6-Architektur kompiliert und nutzt keine Erweiterungen von ARMv7 oder ARMv8. Mag sein, dass sich das in Zukunft ändert. (OpenELEC gibt es dagegen in zwei Versionen, eine für ARMv6 und eine für ARMv7/ARMv8.)

Der Umstieg auf ARMv8 bringt aber dennoch Vorteile: Auch wenn die CPU momentan nur wie eine 32-Bit-CPU genutzt wird, so ist die CPU bei gleicher Taktfrequenz schneller als ARMv7. Manche CPU-Kommandos können also in weniger Taktzyklen als bisher erledigt werden. (Die Taktfrequenz der Pi 3 ist ja nur um 33% höher als die des Pi 2. Die restlichen Geschwindigkeitsverbesserungen gehen auf das Konto der ARMv8-Architektur.)

Persönliche Einschätzung

Die Raspberry Pi Foundation ist ihrer Zielsetzung treu geblieben: Der Pi 3 ist in fantastischer Rechner für Bastel- und Steuerungsaufgaben sowie für den Unterrichtseinsatz. Bei gleichbleibendem Preis bietet der Pi 3 eine deutlich höhere Geschwindigkeit sowie WLAN und Bluetooth als Draufgabe — und bleibt doch vollständig kompatibel. Was will man also mehr?

Enttäuscht werden möglicherweise all jene sein, die den Pi für andere Aufgaben einsetzen:

  • Der Pi als Desktop-Rechner: Die Rechenleistung ist mittlerweile für viele Aufgaben ausreichend. Haupthindernis ist die immer noch vergleichsweise lahme Grafik, der mit einem GByte arg limitierte Arbeitsspeicher und die fehlende Möglichkeit, eine externe Festplatte oder SSD in einer vernünftigen Geschwindigkeit anzusprechen.
  • Der Pi als Mediencenter: Hier hat sich der Raspberry Pi ja schon bisher bewährt. Aber wer auf besseres Audio, 4k-Grafik, H.265-Hardware-Unterstützung etc. gehofft hat, wird enttäuscht sein.

  • Der Pi als NAS/Server: Auch hier gibt es wenig Verbesserungen. Die Rechenleistung ist OK, aber es hapert an der I/O-Anbindung: Weiterhin kein GBit-Netzwerk, weiterhin kein SATA oder USB3. Immerhin ist der neue WLAN-Adapter vom einen USB-Bus getrennt, der weiterhin die Ethernet-Buchse und die vier USB-Anschlüsse versorgt. Erfreulicherweise ist der interne WLAN-Adapter Host-Adapter-fähig. Schade nur, dass es für den WLAN-Adapter keinen Anschluss für eine externe Antenne gibt.

Ich habe die Vermutung, dass wir irgendwann einen Pi der neuen Generation erhalten werden, der manche der obigen Wünsche erfüllt. Aber dann werden vermutlich viele bedauern, dass der Pi der Zukunft spürbar mehr kostet, inkompatibel zu seinen Vorgänger-Modellen ist und mehr Strom braucht. Und insofern bin ich mit dem aktuellen Pi 3 absolut glücklich.

Zitat Eben Upton (Quelle): „We’re kind of at the end of that particular roadmap. I would expect a longer pause, a couple of years at least, before any kind of major bump to the platform,“ he said.

Quellen

Pläne für Swift 3.0

$
0
0

Mit der Geheimniskrämerei ist es vorbei: Da Swift ein Open-Source-Projekt ist, verläuft die Entwicklung nun deutlich transparenter. Dieser Beitrag fasst zusammen, wie Swift 3 voraussichtlich aussehen wird. Diese Pläne ändern sich momentan laufend. Dieser Beitrag wird deswegen regelmäßig aktualisiert. (Erste Version 11.12.2015, letztes Update: 16.3.2016.)

Die Basis: Swift 2.2

Voraussichtlich noch im März 2016 wird Swift 2.2 fertig werden. Für dieses Blog habe ich einen ausführlichen Überblick über alle bekannten Neuerungen in Swift 2.2 verfasst. Der Vollständigkeit halber fasse ich die wichtigsten Swift-2.2-Neuerungen hier nochmals in Kurzform zusammen:

  • keine klassische-for-Schleife mehr (deprecated in Swift 2.2, nicht mehr verfügbar in Swift 3)
  • kein x++/x-- mehr (ebenso)
  • neue Selektor-Syntax
  • associatedtype-Schlüsselwort für generische Parameter von Protokollen (anstelle von typealias)
  • keine var-Parameter mehr
  • Swift-Schlüsselwörter dürfen als Parameternamen verwendet werden
  • Tupel-Vergleiche

Die Fertigstellung von Swift 3 ist für den Herbst 2016 geplant. Diese Seite konzentriert sich im Weiteren auf die geplanten Neuerungen in Swift 3.0 relativ zu Swift 2.2.

Binärkompatibilität

Auch Apple ist sich bewusst, dass die ständigen Änderungen in Swift für all jene, die schon produktiv mit Swift arbeiten, mühsam sind. Mit Version 3.0 sollen aber möglichst viele Interna und Strukturen so weit fixiert werden, dass nicht mehr bei jedem Update alles neu kompiliert werden soll.

Verbesserte Schnittstellen zu den Bibliotheken

Die Nutzung der für Objective C konzipierten Bibliotheken und XxxKits unter Swift ist sperrig, unübersichtlich und un-swift — das bemerkt jeder, der auch nur wenige Tage mit Swift programmiert. Auch in meinem Buch habe ich das mehrfach kritisch angemerkt.

Nicht einmal Apple kann deswegen alle Bibliotheken neu implementieren. Stattdessen wurde beschlossen, einfach die Schnittstellen zu den Bibliotheken speziell für Swift zu optimieren. Das ist ein relativ pragmatischer Ansatz, der zwar keine perfekte Lösung verspricht, aber zumindest eine große Verbesserung.

Details können Sie in Proposal 0005, Proposal 0006, Proposal 0023 sowie in der Big-three-Zusammenfassung von Erica Sadun nachlesen. Die ursprünglich in diesem Zusammenhang geplante Abschaffung des NS-Präfix in diversen Klassennamen wurde vorläufig zurückgestellt. Ob es dazu kommen wird, ist offen.

In diesem Zusammenhang ebenfalls erwähnenswert ist der bereits akzeptierte Proposal 0033: Demzufolgen sollen in Objective-C-Code deklarierte Konstanten in Swift als Enums oder Structs verfügbar gemacht werden. Das erhöht nicht nur die Lesbarkeit des Codes, sondern auch die Typensicherheit.

Core Libraries

Die Foundation-Bibliothek und die Bibliotheken libdispatch und XCTest sollen in Swift neu implementiert werden. Das primäre Ziel ist hier weniger die Optimierung der Schnittstelle zu Swift. Vielmehr sollen für Linux, Windows etc. zumindest Grundfunktionen zur Verfügung gestellt werden. Momentan ähnelt Swift unter Linux ja einer Insel in der Mitte des Pazifik: Sie können damit Algorithmen testen, aber nicht viel mehr. Jeder Zugriff auf Funktionen/Bibliotheken des Betriebssystem ist mit hohem (Code-)Aufwand verbunden. Indem dem Swift eine Open-Source-Version der Foundation-Bibliothek zur Seite gestellt wird, soll dieses Problem ein wenig gemindert werden. Weitere Informationen können Sie hier nachlesen. Wie weit die Arbeiten vorangeschritten sind, geht aus dieser Status-Seite hervor.

Generics

Der Umgang mit generische Typen soll in Swift 3 perfektioniert werden. In der Swift-3-Entwicklerversion bereits implementiert ist die generische Erweiterung von typealias (Ankündigung in der swift.dev-Mailing-Liste):

typealias StringDictionary<T> = Dictionary<String, T>
typealias IntFunction<T> = (T) -> Int
typealias MatchingTriple<T> = (T, T, T)
typealias BackwardTriple<T1,T2,T3> = (T3, T2, T1)

Zu den weiteren geplanten Neuerungen zählen rekursive Contraints. Eine recht detaillierte Zusammenstellung dessen, was hier für Swift 3.0 geplant ist, geben die beiden folgenden Beiträge/Diskussionen auf der der swift.evolution-Mailingliste:

In diesem Zusammenhang ist auch dieser Grundlagentext lesenswert. Er fasst die Konzepte der Generics-Implementierung auf der Basis von Swift 2 zusammen.

Sonstiges

  • Keine Curried-Funktionen mehr: Swift bietet momentan die Möglichkeit, Curried Functions zu bilden, also Funktionen, bei denen vorerst nur ein Teil der Parameter festgelegt wird und der Rest weiter als Funktion genutzt werden kann. Diese relativ komplexe Syntax, auf die ich in meinem Buch gar nicht eingegangen bin, soll in Swift 3 eliminiert werden. Links: Proposal 0002, Wikipedia, Introduction to Function Currying in Swift, Instance Methods are Curried Functions in Swift, Beschreibung im Swift-Buch von Apple
  • Attributparameter: Parameter von Funktionen/Methoden werden in der Form f(name:wert) übergeben, also z.B. f(a:1, b:2). Diese Syntax soll in Zukunft auch für Attribute gelten, also z.B. @availability(iOS, introduced: 2.0) anstelle von @availability(iOS, introduced=2.0). Details: Proposal 0040

  • Neue inout-Syntax: inout-Parameter werden in Zukunft so gekennzeichnet: f(paraname: inout Typename). Die bisherige Syntax lautete „f(inout paraname: Typename)`. Details: Proposal 0031

  • Playground-Literale: Im Playground können Literale für Farben, Bilder und Dateien aktuell z.B. in der Form [#Color(colorLiteralRed: red, green: green, blue: blue, alpha: alpha)#] dargestellt werden, also zwischen [# und #]. Die neue Syntax lautet #colorLiteral(...), #imageLiteral(...) und #fileLiteral(...). Details: Proposal 0039

  • Alle Parameter sind gleich: Momentan ist der erste Parameter einer Methode unbenannt, alle weiteren sind benannt. Die Funktion func f(a:Int, b:Int) wird also mit f(1, b:2) aufgerufen. In Swift 3.0 werden dagegen alle Parameter einheitlich behandelt. Die erwähnte Funktion f muss dann mit f(a:1, b:2) aufgerufen werden, was wesentlich logischer ist.
    Details: Proposal 0046

Das kommt vielleicht

Das ist nicht bzw. frühestens in Swift 4 geplant

  • Multithreading/Asynchrone Programmierung: Swift 3 wird keine inhärenten Funktionen zur nebenläufigen Programmierung erhalten. Swift greift hierfür auf Foundation-Klassen, pthreads, libdispatch etc. zurück. Eine Swift-interne Implementierung asynchroner Funktionen ist aber für Swift 4 angedacht.

  • Bibliotheken: Apple kann und will nicht alle iOS-, OS-X-Bibliotheken etc. neu implementieren. Die Foundation-Bibliothek ist eine Ausnahme, alle anderen Bibliotheken sollen im Wesentlichen bleiben wie sie sind. Allerdings wird es massive Änderungen geben, wie die Methoden der iOS- und OS-X-Bibliotheken von Swift aus genutzt werden können (siehe die Überschrift »Verbesserte Schnittstellen zu den Bibliotheken« weiter oben).

  • Sprachänderungen, die Apple ablehnt: Auf der Seite Commonly Rejected Changes finden Sie eine Zusammenstellung häufig vorgeschlagener Änderungswünsche, die wenig bzw. keine Aussicht auf Erfolg haben, weil sie von Apple festgelegten Sprachdesign-Richtlinien widersprechen. Dazu zählen die Veränderung des Ternary Operators, die Abschaffung geschwungener Klammen zugunsten einer syntaktisch vorgeschriebenen Einrückung (wie in Python), eine andere Definition der Closure-Syntax oder die Verwendung einfacher Apostrophe für Character-Literale (wie in Java).

Swift-Version feststellen

Um die aktuelle Swift-Version Ihrer Xcode-Installation festzustellen, führen Sie in einem Terminal-Fensters swift -version aus. Xcode 7.2 enthält die Swift-Version 2.1.1, Xcode 7.3 Beta die Swift-Version 2.2 (zuletzt getestet Mitte März 2016):

swift -version
  Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
  Target: x86_64-apple-darwin15.2.0

cd /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
./swift -version
  Apple Swift version 2.2 (swiftlang-703.0.17.4 clang-703.0.28)
  Target: x86_64-apple-macosx10.9

Quellen

Swift 2.2

$
0
0

Voraussichtlich ist Swift 2.2 die letzte Swift-Version vor dem großen, für Herbst geplanten Update auf Swift 3. Swift 2.2 bietet im Vergleich zu Swift 2.0/2.1 einige neue Funktionen. Beim Design von Swift 2.2 war die Kompatibilität zu vorhandenem Swift-2-Code ein wichtiges Ziel. Die meisten Neuerungen sind als Ergänzungen/Erweiterungen konzipiert, die optional verwendet werden können, aber keinen Einfluss auf vorhandenen Code haben.

Dennoch zeigt Swift 2.2 bereits in einigen Punkten die Richtung an, in die sich Swift weiterentwickelt. So wurden diverse Sprachmerkmale von Swift als deprecated gekennzeichnet. Das betrifft z.B. klassische for-Schleifen, die in Swift 2.2 weiter ausgeführt werden, in Xcode aber als deprecated gekennzeichnet werden. Diese Kennzeichnung gibt Entwicklern die Möglichkeit, schon jetzt damit zu beginnen, ihren Code möglichst Swift-3-konform zu gestalten.

Diese Artikel fasst die Neuerungen auf der Basis von Xcode 7.3 Beta 5 zusammen. Ich werde den Text nach der Freigabe von Xcode 7.3 nochmals aktualisieren. Lesen Sie auch die Zusammenfassung über den aktuellen Stand der Pläne für Swift 3!

Neu: Tupel-Vergleiche

Bis einschließlich Swift 2.1 können Tupel nicht verglichen werden. Swift 2.2 stellt für Tupel mit bis zu sechs Elementen die Operationen == und != zur Verfügung.

//: Tupel vergleichen (zulässig für Tupel mit bis zu sechs Elementen)
let tupel1 = (1, 2)
let tupel2 = (1, 2)
if tupel1 == tupel2 {
  print("Die beiden Tupel sind identisch.")
}

// das folgende Beispiel funktioniert nicht, weil die Tupel zu viele Elemente haben
let tupel3 = (1, 2, 3, 4, 5, 6, 7)
let tupel4 = (1, 2, 3, 4, 5, 6, 7)
if tupel3 == tupel4 {
  print("Die beiden Tupel sind identisch.")
}

Deprecated: Tupel Splat

Und weil wir schon bei Tupel sind: Die wenig bekannte Tuple-Splat-Syntax, die es erlaubt, ein Tupel mit n Elementen an eine Funktion/Methode mit ebenso vielen Parametern zu übergeben, gilt nun als deprecated und wird in Swift 3 ganz verschwinden. Der Grund: Der Code ist schwer zu lesen und stiftet Verwirrung. Der Aufruf g(tupel) sieht so aus, als würde an g nur ein Parameter übergeben.

func g(a a:Int, b:Int, c:Int) -> Int {
  return a+b+c
}
let tupel = (a:2, b:4, c:8)
print( g(tupel) )   // Ausgabe: 14

Deprecated: Inkrement- und Dekrement-Operator

Die Operatoren ++ und -- gelten als deprecated. In vielen Fällen können Sie i++ oder ++i einfach durch i+=1 ersetzen. Wenn Sie aber den bisherigen oder aktuellen Wert gleichzeitig an eine Funktion/Methode übergeben, dann müssen Sie Ihren Code umbauen:

// in Swift 2.2 deprecated, aber noch erlaubt
var x=3
while(x>0) {
  print(--x)
}

// Swift-3-kompatibler Code
var x=3
while(x>0) {
  x-=1
  print(x)
}

Deprecated: Die klassische for-Schleife

Die klassische, aus C vertraute for-Schleife wird in Swift 2.2 letztmalig akzeptiert. Die Entwickler argumentieren, dass sich der Code in den meisten Fällen eleganter formulieren lässt — und oft trifft dies auch zu, vor allem wenn die zu verarbeitenden Daten ohnedies bereits in Arrays, Sets oder anderen Aufzählungsklassen vorliegen. Bei anderen Aufgabenstellungen ist der Verzicht auf die klassische for-Schleife hingegen lästig und zwingt zu while-Schleifen oder anderen Konstrukten, die den Code in der Regel nicht besser lesbar machen. Insofern ist die Abschaffung der for-Schleife nicht vollständig nachvollziehbar.

Wie dem auch sei … Einfache Schleifen im Stil von for var i=start; i<end; i++ machen wenig Probleme und können mit for i in start..<end formuliert werden. Xcode unterstützt Sie dabei mit Fix-it-Vorschlägen.

// Swift 2.2: deprecated, aber OK
let max=3  // exklusive
for var i=0; i<max; i++ {
  print(i)
}

// Lösung für Swift 3
for i in 0 ..< max {
  print(i)
}

Schon schwieriger ist es, eine Schleife rückwärts zu durchlaufen:

// Swift 2.2: deprecated, aber OK
for var i = max-1; i>=0; i-=1 {
  print(i)
}

// Lösung für Swift 3
for i in (0..<max).reverse() {
  print(i)
}

// alternative Lösung für Swift 3
var i = max-1
while(i>=0) {
  print(i)
  i-=1
}

Schleifen mit Fließkommavariablen sind generell selten eine gute Idee. Höchste Zeit, den Code umzustellen!

// Swift-2.2-Code, +0.0001 wegen möglicher Rundungsfehler
for var x=0.0; x <= 2 * M_PI + 0.0001; x += M_PI/10 {
  print(x)
}
// besserer Code, Swift-3-kompatibel
for n in 0...20 {
  print(M_PI / 10.0 * Double(n))
}

Am allgemeingültigsten ist immer der Umbau von for nach while:

// in Swift 2.2 noch erlaubt
for var x=1.0; x<100; x*=1.3 {
  print(x)
}

// Swift-3-kompatibler Code
var x=1.0
while(x<100) {
  print(x)
  x*=1.3
}

Neu: typealias versus associatedtype

In Swift 2 hat das Schlüsselwort typealias zwei Bedeutungen: Einerseits wird es — seinem Namen entsprechend — verwendet, um einen Alias für einen vorhandenen Datentyp zu definieren. Andererseits dient es zur Deklaration von generischen Typen in Protokollen. Beginnend mit Swift 3 muss für diesen zweiten Fall das neue Schlüsselwort associatedtype verwendet werden:

// Swift-2-Code, wird in 2.2 mit deprecated-Warnung akzeptiert
protocol Generator {
  typealias Element
  mutating func next() -> Element?
}

// korrekter Swift-3-Code
protocol Generator {
  associatedtype Element
  mutating func next() -> Element?
}

// noch logischer wäre meiner Ansicht nach
// protocol Generator<Element> { ... }
// diese Syntax ist aber weder in Swift 2 noch in Swift 3 zulässig

Neue Selektor-Syntax

Momentan müssen Referenzen auf Methoden (action-Parameter) in der Objective-C-Syntax als Zeichenketten angegeben werden. Der Swift-Compiler kann diese Zeichenkette nicht verifizieren. Bei Tipp- oder Syntaxfehlern tritt zu Laufzeit ein Fehler auf. In Swift 2.2 kann der Selektor in der Form #selector(Klasse.methode) bzw. #selector(Klasse.methode(parameter ...)) definiert werden. Ab Swift 3.0 ist diese Syntax zwingend. Das folgende Beispiel illustriert die Syntax. Xcode hilft bei der Umwandlung mit Fix-its.

// deprecated ab Swift 2.2
btn.addTarget(self,
  action: "buttonAction:",
  forControlEvents: .TouchUpInside)

// erlaubt ab Swift 2.2, erforderlich ab Swift 3
btn.addTarget(self,
  action: #selector(ViewController.buttonAction(_:)),
  forControlEvents: .TouchUpInside)

Neu: Code-Zweige für verschiedene Swift-Versionen

Sie können in den Swift-Code nun verschiedene Zweige einbauen, die je nach Swift-Version berücksichtigt bzw. ignoriert werden:

#if swift(>=3)
  print("Ein Blick in die Zukunft")
#else
  print("Noch mit Swift 2.n unterwegs")
#endif

Neu: Schlüsselwörter als Parameternamen

Die meisten Swift-Schlüsselwörter dürfen ab Swift 2.2 als Parameternamen verwendet werden. Insbesondere ist nun in als Parametername erlaubt. Innerhalb der Funktion müssen derartige Parameternamen in nach rechts gerichtete Apostrophe (Backticks) gestellt werden.

func f(in in:Int, inout out:Int) {
  out = `in` * 2
}
var x:Int = 0
f(in:2, out: &x)
print(x)  // Ausgabe 4

Deprecated: var-Parameter

Parameter von Funktionen und Methoden können momentan mit dem zusätzlichen Schlüsselwort var gekennzeichnet werden. Das bedeutet, dass diese Parameter innerhalb der Funktion/Methode verändert werden darf. Die Veränderung gilt allerdings nur innerhalb der Funktion/Methode, nicht aber nach außen hin. Das ist selten zweckmäßig und stiftet außerdem eine Menge Konfusion mit dem im vorigen Beispiel eingesetzten Schlüsselwort inout, das zur Deklaration von Referenz-Parametern dient. inout wird es weiterhin geben, aber var-Parameter gelten beginnend mit Swift 2.2 als deprecated und werden in Swift 3 ganz verschwinden.

// var-Parameter sind jetzt deprecated und ab Swift 3 nicht mehr zulässig
func h(var a:Int) {
  a+=1
  print(a)
}
h(3)  // Ausgabe 4

Sonstiges

  • removeFirst(): Für Arrays und andere Datentypen, die das Protokoll RangeReplaceableCollectionType implementieren, gibt es jetzt auch die praktische Methode removeFirst. (removeLast gab es ja schon immer.)
  • Neue Schlüsselwörter in Markdown-Kommentaren: In Markdown-Kommentaren konnten Sie schon bisher Schlüsselwörter wie parameter name:, returns: und throws: verwenden, um die Parameter eine Methode/Funktion zu dokumentieren, den Rückgabewert zu beschreiben oder auf mögliche Fehler hinzuweisen. Zu diesen Schlüsselwörtern kommen nun keyword:, recommended: und recommendedover: hinzu.

  • Naming Functions with Argument Labels: Schon bisher konnten Sie Funktionen/Methoden als Referenz übergeben oder in einer Variablen speichern (let myfunc = someView.insertSubview). Diese Syntax ist aber problematisch, wenn es mehrere gleichnamige Varianten der Funktion/Methode gibt, die sich nur durch die Parameterliste unterscheiden. Neu in Swift 2.2 ist die Möglichkeit, nun auch die Parameter anzugeben um so klar zu machen, welche Variante Sie meinen: let myfunc = someView.insertSubview(_:aboveSubview:)

  • Constraining AnySequence.init: Die init-Funktion von AnySequence hat sich geändert. Wenn Sie eigene Klassen von AnySequence abgeleitet haben, müssen Sie gegebenenfalls deren init-Code anpassen.

  • getDemangledTypeName: Die nie dokumentierte Funktion _stdlib_getDemangledTypeName ist verschwunden. Den Typ einer Instanz ermitteln Sie am besten mit String(obj.dynamicType). Die Ergebnisse sind allerdings nicht immer exakt dieselben. Beispielsweise lieferte _stdlib_getDemangledTypeName den Typnamen NSDate, während String(mydate.dynamicType) die Zeichenkette __NSDate zurückgibt.

  • #file, #line etc.: Im Programmcode können Sie mit __FILE__, __LINE__ etc. auf den Dateinamen, die aktuelle Zeile etc. zugreifen, z.B. um diese Daten in Debug-Code zu integrieren. Diese Schreibweise gilt nun als deprecated. Neu und optisch weit weniger aufdringlich ist die neue Syntax #file, #line, #column, #function. Beispiel: let fname = #file oder let linenr = #line.

Geplant, aber noch nicht implementiert

Neuerungen im Playground

Die Gestaltungs- und Steuerungsmöglichkeiten in Playgrounds werden weiter aufgewertet, vermutlich, damit diese Dokumente sich noch besser zum Einsatz für Dokumentation und Unterricht eignen. So können nun auch Videos eingebettet werden, sofern diese zuvor den Ressourcen des Playgrounds hinzugefügt wurden.

![Beschriftung](filename.mp4 width="640" height="480" poster="vorschaubild.png")

Mit gewissen Einschränkungen sind in Playgrounds nun Live-Interaktionen mit per Playground-Code erzeugten iOS- oder OS-X-Steuerelementen erlaubt.

Hinter den Kulissen wurde die Interna der Playground-Darstellung verändert. Das ist unter anderem daran erkennbar, dass Markdown-Kommentare jetzt einer anderen Schrift angezeigt werden.

Unverändert läuft Code in Playgrounds relativ langsam. Bei der Eingabe neuen Codes kommt es immer wieder zu Problemen. Bei meinen Tests brach die Kommunikation zwischen dem Playground und dem Swift-Compiler immer wieder ab (failed to launch stub for playground execution). Manchmal gelingt die Wiederaufnahme der Kommunikation, andernfalls ist ein Neustart von Xcode notwendig.

Beispieldateien zu meinem Swift-2-Buch

Für alle, die schon jetzt mit den Xcode-7.3-Betas arbeiten, habe ich auf der Basis der Beta 5 alle überarbeiteten Beispieldateien zusammengestellt. Die Beispiele sind nun frei von deprecated-Warnungen. Die Top-Drei der Änderungen waren: for-Schleifen, x++/x-- sowie Selektoren. Insgesamt war der Umbau aller Beispiele in ca. einem halben Tag erledigt.

Beispieldateien Swift 2.2 (ZIP)

Sobald Apple Xcode 7.3 samt Swift 2.2 frei gibt, werde ich alle Beispiele aus meinem Buch nochmals überprüfen und dann eine aktualisierte Fassung zum Download zur Verfügung stellen.

Quellen

Implementierte oder geplante Proposals für Swift 2.2

dynamicType und getDemangledTypeName

Erste Vorschau auf Ubuntu 16.04

$
0
0

In ca. sechs Wochen wird Ubuntu 16.04 fertig werden. Dieser Artikel wirft einen ersten Blick auf die wichtigsten Neuerungen.

(Update 16.3.2016: Ubuntu 16.04 enthält doch PHP-7-Pakete.)
(Update 19.3.2016: Ubuntu 16.04 verwendet Systemd und Journal. Das Dock am unteren Bildschirmrand ist fix. apt wird als neues Kommando zur Paketinstallation vorgeschlagen.)

Kein binärer AMD-Grafiktreiber mehr (fglrx)

Für AMD-Grafikkarten gibt es in Ubuntu 16.04 nur noch die Open-Source-Treiber radeon/amdgpu. In der Vergangenheit war es problemlos möglich, alternativ dazu den proprietären Treiber von AMD zu installieren. Diese Möglichkeit besteht nun nicht mehr. Den proprietären NVIDIA-Treiber wird Ubuntu hingegen weiterhin zur Verfügung stellen.

Integration des Dateisystems zfs

Ubuntu 16.04 soll standardmäßig das Dateisystem zfs integrieren. Dieses Dateisystem wurde ursprünglich von Sun für das Betriebssystem Solaris entwickelt. Es untersteht zwar wie der Linux-Kernel einer Open-Source-Lizenz. Die Lizenzen von Linux und zfs sind aber nicht kompatibel zueinander. Die Integration von zfs in den Linux-Kernel ist deswegen rechtlich umstritten.

Für Desktop-Anwender ist zfs nicht übermäßig interessant, aber für den Server-, Virtualisierungs- und Docker-Einsatz genießt zfs den Ruf als das beste verfügbare Unix-Dateisystem. btrfs bietet ähnliche Funktionen, ist aber nicht im gleichen Maß ausgereift.

Init- und Logging-System

Ubuntu verwendet als Init-System nun Systemd, als Logging-System Journal. Die Steuerungskommandos lauten systemctl und journalctl. Für Desktop-Anwender ergeben sich daraus keine Änderungen, wohl aber für Administratoren.

Kein Python 2 per Default

Die Desktop-Version von Ubuntu 16.04 soll standardmäßig nur noch Python 3 enthalten. Python-2-Pakete stehen weiterhin zur Verfügung, und zwar in der main-Paketquelle (LTS!).

Schlechtere Samba-Integration

Das außerordentlich praktische Paket libpam-smbpass steht nicht mehr zur Verfügung. Es hat sich in der Vergangenheit darum gekümmert, Linux- und Samba-Passwörter zu synchronisieren und hat beim unkomplizierten Einrichten eigener Samba-Shares geholfen. Das zugrundeliegende PAM-Modul wird vom Samba-Projekt aber nicht mehr unterstützt.

Wieder einmal: eine alte Nautilus-Version

Ubuntu 16.04 wird natürlich die meisten Software-Komponenten aktualisieren — vom Kernel über Unity bis zu LibreOffice. Eine Ausnahme ist wieder einmal der Gnome-Dateimanager Nautilus, der in der uralten Version 3.14 enthalten sein wird. (Aktuell wäre ab April 2016 die Version 3.20.)

Keine Werbung mehr im Startmenü

Eindeutig erfreulich ist die Entscheidung der Ubuntu-Entwickler, auf die unsägliche Einblendung von Werbung im Startmenü (»Online-Suchergebnisse«) standardmäßig zu verzichten.

Dock am unteren Bildschirmrand

Das Dock war bisher auf den linken Bildschirmrand fixiert. In Ubuntu 16.04 kann es nun auch an den unteren Bildschirmrand verschoben werden. (Persönlich war ich immer der Meinung, dass die Anordnung links vernünftig ist. Aber mehr Wahlmöglichkeit kann nicht schaden.)

Der entsprechende Unity-Patch ist seit 19.3. offiziell verfügbar. Die Konfiguration muss allerdings noch per Kommando erfolgen:

gsettings set com.canonical.Unity.Launcher launcher-position Bottom

Rückgängig mit:

gsettings set com.canonical.Unity.Launcher launcher-position Left

Eine Anordnung am rechten Rand ist momentan nicht vorgesehen.

Das Dock am unteren Bildschirmrand
Das Dock am unteren Bildschirmrand

Keine Spur von MIR und Unity 8

Die seit Jahren angekündigte Umstellung des Grafiksystems auf MIR und des Desktops auf Unity 8 wird auch in Ubuntu 16.04 nicht stattfinden. Zum Trost für alle Fans von MIR kann gesagt werden, dass auch Fedora den Umstieg auf das Grafiksystem Wayland einmal mehr verschoben hat.

Wer Unity 8 und MIR ausprobieren will, kann die erforderlichen (aber noch nicht stabilen) Pakete wie folgt installieren:

sudo apt-get install unity8-desktop-session-mir

Beim Login können Sie nun die Unity8-Mir-Session auswählen. Glücklich werden Sie damit nicht werden — es funktioniert praktisch nichts. Unity 8 hat in dieser Form nicht einmal die Qualität einer Alpha-Version.

Gnome Software ersetzt das Ubuntu Software Center

Eine andere Eigenentwicklung von Ubuntu wird offensichtlich eingestellt. Das Ubuntu Software Center soll zugunsten des Programms »Gnome Software« eliminiert werden. Gnome Software ist aus meiner Sicht freilich auch kein Lichtblick, aber wer schon ein bißchen Linux-Erfahrung hat, kann ja weiterhin apt-get install xy im Terminal ausführen.

apt als Alternative zu apt-get

Schon bisher hatten Sie bei der Installation und Verwaltung von Paketen auf Kommandoebene die Wahl zwischen apt-get und aptitude. Dazu kommt nun mit apt ein drittes Kommando hinzu. Wenn Sie ein nicht existierendes Kommando auszuführen versuchen, rät Ubuntu nun dazu, dieses mit apt zu installieren.

emacs
Das Programm »emacs« ist in folgenden Paketen enthalten:
 * emacs24
 * emacs24-nox
 * e3
 * emacs24-lucid
 * jove
Versuchen Sie: apt install <ausgewähltes Paket>

Die Syntax von apt ist ähnlich wie die von apt-get und aptitude, nennenswerte Vorteile sind mir nicht aufgefallen.

Software-Versionen

Auch wenn sich die eine oder andere Version sicher noch ändern wird, hier schon mal ein Überblick über die Software-Versionen, die in den Testversionen von Ubuntu 16.04 aktuell (Mitte März 2016) zum Einsatz kommen:

Basis           Desktop            Programmierung     Server
--------------  ------------------ --------------    --------------
Kernel     4.4  Gnome        3.18  bash       4.3    Apache    2.4
glibc     2.21  Firefox        45  gcc        4.9    CUPS      2.1
X-Server  1.18  Gimp          2.8  Java       7/8    MySQL     5.6
GRUB      2.02  LibreOffice   5.1  PHP          7    OpenSSH   7.2
Systemd    229  Thunderbird    38  Python     3.5    qemu/KVM  2.5
                Unity         7.4                    Postfix   3.0
                                                     Samba     4.3

Einzelne Gnome-Programme werden in älteren, manche in neueren Versionen ausgeliefert, z.B.:

  • gnome-calendar: 3.19 (daraus wird vorauss. 3.20)
  • gnome-font-viewer: 3.16
  • gnome-software: 3.19 (daraus wird vorauss. 3.20)
  • nautilus: 3.14

Etwas befremdlich ist die recht alte gcc-Version 4.9. Aktuell ist 5.3, Fedora Rawhide verwendet gar schon die noch nicht finale Version 6.0.

MySQL 5.7 wäre natürlich schön gewesen, aber da war/ist das Timing wohl zu knapp. MariaDB-Pakete in der Version 10.0 gibt es nur in der universe-Paketquelle (also ohne LTS-Wartungsgarantien).

PHP-Pakete liegen in main sowohl in Version 5.6 als auch in Version 7 vor. tasksel install lamp installiert aber automatisch PHP 7.

Dennoch das beste Desktop-Linux?

Die aktuelle Zusammenstellung der Neuerungen lässt keine grenzenlose Begeisterung aufkommen. Echte Innovationen für den Linux-Desktop sehen anders aus. Dennoch bin ich zuversichtlich, dass Ubuntu auch in Version 16.04 das beste Desktop-Linux bleiben wird. Die Vorzüge von Ubuntu 16.04 sind dieselben wie die von Version 14.04: Ubuntu läuft stabil und ist einfach zu bedienen — was will man also mehr?

Die Alleinstellung von Ubuntu als »die« Desktop-Linux-Distribution hat freilich auch mit einem immer eklatanteren Mangel an Alternativen zu tun: openSUSE und Fedora sind zu instabil/experimentell, Debian ist nach wie vor nur bedingt einsteigertauglich. Mein Tipp für Ubuntu-Verweigerer bleibt CentOS, auch wenn man dort Abstriche bei der Aktualität der Software-Pakete machen muss. Plan B wäre Linux Mint, aber riesige Vorteile im Vergleich zu Ubuntu habe ich da (in Gegensatz zu anderen Linux-Fans) nie wirklich erkennen können. Den größten Nachteil von Mint sehe ich in der Abhängigkeit von einem winzigen Entwickler-Team.

Quellen

Let’s-Encrypt-Zertifikate für Web und Mail unter Ubuntu 16.04

$
0
0

Das Projekt Let’s Encrypt bietet kostenlose Zertifikate an, die von den meisten gängigen Webbrowsern akzeptiert werden. Wie Sie diese Zertifikate unter Ubuntu 16.04 für Apache, Postfix und Dovecot einrichten, ist Thema dieses Beitrags. Dabei setze ich ein grundsätzliches Vorwissen zur HTTPS-Konfiguration von Apache sowie zur Konfiguration von Postfix und Dovecot voraus. Hier geht es nur um das Einrichten der Zertifikate.

Anmerkung: Let’s Encrypt befindet sich seit einigen Monaten in der Phase eines öffentlichen Beta-Tests. Es wurden zwar schon über eine Million Zertifikate ausgestellt, aber es kann sein, dass sich Spielregeln oder Client-Programme noch ändern. Ubuntu 16.04 ist momentan (Mitte März 2016) ebenfalls noch nicht final; bei der getesteten Ubuntu-Server-Variante sind aber keine großen Umwälzungen mehr zu erwarten.

Update 20.3.2016: letsencrypt renew anstelle von le-renew

Für das Let’s-Encrypt-Projekt gelten drei Grundannahmen, die sich von den etablierten Zertifizierungsstellen wie Thawte oder Verisign unterscheiden:

  • Überprüft wird nur die Domain, nicht aber, wer Sie sind bzw. ob es Ihre Firma gibt. Die Zertifikate haben damit die gleiche Qualität wie die jeweils kostengünstigsten Zertifikate kommerzieller Anbieter. Für private/kleine Webauftritte ist das absolut ausreichend. Let’s Encrypt richtet sich aber nicht an Online-Shops, große Firmen, Banken etc., bei deren Zertifikaten (gegen gutes Geld) auch der Inhaber der Domain überprüft wird.
  • Die Installation der Zertifikate erfolgt weitgehend automatisiert durch das Kommando letsencrypt. Damit entfällt das umständliche Handling mit Schlüsseln und Zertifikatsdateien, die per E-Mail versendet bzw. manuell heruntergeladen werden müssen. In diesem Punkt bietet Let’s Encrypt mehr Komfort als kommerzielle Anbieter.

  • Die Zertifikate sind generell nur 90 Tage gültig. Das ist nicht weiter schlimm — ich werde Ihnen gleich zeigen, wie Sie den Zertifikatserneuerungsprozess automatisieren können.

Hinweis: Um Missbrauch zu vermeiden, gibt es strikte Limits, wie viele Zertifikate für eine Domain in einer bestimmten Zeit erzeugt werden dürfen:

https://community.letsencrypt.org/t/rate-limits-for-lets-encrypt/6769

Um zu vermeiden, dass Sie diese Limits erreichen, sollten Sie das Kommando letsencrypt für erste Tests die Option --test-cert verwenden. Damit erhalten Sie Zertifikate von einem Test-System. Erst wenn Sie sicher sind, dass alles funktioniert, erstellen Sie die richtigen Zertifikate ohne diese Option.

letsencrypt-Zertifikate für Apache einrichten

Let’s Encrypt stellt das Script letsencrypt zur Verfügung, die beim Einrichten und Installieren der Zertifikate helfen. Unter Ubuntu 16.04 gibt es dieses Scripts sowie diverse Plugins in Form von Paketen. (Das Script letsencrypt soll in Zukunft einen neuen Namen erhalten und losgelöst vom Projekt Let’s Encrypt weiterentwickelt werden (Quelle). Ob das Auswirkungen auf die Pakete für Ubuntu 16.04 hat, lässt sich momemtan nicht abschätzen.)

apt-get install python-letsencrypt-apache

Let’s-Encrypt-Zertifikate für Apache installieren

Um Let’s-Encrypt-Zertifikate anzufordern und für den Webserver Apache zu installieren, führen Sie das folgende Kommando aus. Dabei ersetzen Sie meine-domain.de durch Ihren Domainnamen. Die Zertifikate für smtp.* und imap.* sollen später zur sicheren Konfiguration des Mail-Servers verwendet werden. Wenn Sie nicht vor haben, einen Mail-Server einzurichten, lassen Sie diese beiden Hostnamen weg. Und wenn Sie http://domainname gegenüber http://www.domainname vorziehen, können Sie auch auf die www.*-Variante verzichten. Wenn Sie sicher sind, dass alles klappt, entfernen Sie zuletzt die Option --test-cert und führen das Kommando nochmals aus.

letsencrypt --apache --test-cert -d www.meine-domain.de \
  -d meine-domain.de -d imap.meine-domain.de \
  -d smtp.meine-domain.de

Das Script fordert Sie auf, einen E-Mail-Namen anzugeben. Über diese E-Mail werden Sie verständigt, wenn Ihre Zertifikate ablaufen. Wenn letsencrypt in der Apache-Konfiguration keine Datei mit ServerName-Einstellungen findet, die mit den von Ihnen angegebenen Hostnamen übereinstimmen, müssen Sie in einem weiteren Dialog auswählen, in welche Apache-Konfigurationsdatei die SSL-Konfiguration eingetragen wird. Außerdem können Sie entscheiden, ob Ihre Webseite auch via HTTP zugänglich sein soll, oder ob HTTPS das einzig erlaubte Protokoll ist.

letsencrypt fordert nun beim Let’s-Encrypt-Projekt die für Sie generierten Zertifikate an, lädt diese herunter, installiert alle erforderlichen Dateien in das Verzeichnis /etc/letsencrypt, verändert die Apache-Konfiguration und startet Apache schließlich neu.

Das folgenden Zeilen zeigen beispielshaft zwei geänderte Apache-Konfigurationsdateien. Aus Platzgründen wurden die meisten Einstellungen dabei über zwei Zeilen verteilt.

# z. B. in der Datei /etc/apache2/sites-available/default-ssl.conf
...
SSLCertificateFile
  /etc/letsencrypt/live/www.meine-domain.de/fullchain.pem
SSLCertificateKeyFile
  /etc/letsencrypt/live/www.meine-domain.de/privkey.pem
ServerName    meine-domain.de
ServerAlias   imap.meine-domain.de
ServerAlias   smtp.meine-domain.de
# Datei /etc/apache2/sites-available/000-default-le-ssl.conf
...
SSLCertificateFile
  /etc/letsencrypt/live/www.meine-domain.de/fullchain.pem
SSLCertificateKeyFile
  /etc/letsencrypt/live/www.meine-domain.de/privkey.pem
Include
  /etc/letsencrypt/options-ssl-apache.conf
ServerName www.meine-domain.de

Die beiden ServerAlias-Zeilen für die Hostnamen imap.* und smtp.* sind natürlich überflüssig. Entfernen Sie die beiden Zeilen mit einem Editor und fordern Sie Apache auf, die Konfiguration neu einzulesen:

service apache2 reload

Nach einem ersten Test, ob https://www.meine-domain.de und https://meine-domain.de in einem Webbrowser angezeigt werden können, sollten Sie Ihre HTTPS-Konfiguration noch über die Seite https://www.ssllabs.com kontrollieren. Diese Seite führt umfassende Tests durch, ob Apache nach allen Regeln der Kunst sicher konfiguriert ist.

https://www.ssllabs.com/ssltest/analyze.html?d=www.meine-domain.de

SSL Labs ist mit der HTTPS-Konfiguration zufrieden
SSL Labs ist mit der HTTPS-Konfiguration zufrieden

Automatische Erneuerung der Let’s-Encrypt-Zertifikate

Mit dem openssl-Kommando können Sie ein Blick in Ihr Zertifikat werfen:

openssl x509 -text -in \
  /etc/letsencrypt/live/www.meine-domain.de/cert.pem

  ...
  Certificate:
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X1
        Validity
            Not Before: Mar 17 12:27:00 2016 GMT
            Not After : Jun 15 12:27:00 2016 GMT
    Subject: CN=www.meine-domain.de
    X509v3 Subject Alternative Name:
             DNS:imap.meine-domain.de,
             DNS:smtp.meine-domain.de,
             DNS:meine-domain.de,
             DNS:www.meine-domain.de

Aus den Daten geht hervor, dass das Zertifikat nur 90 Tage gültig ist. Das erscheint auf den ersten Blick wie eine große Einschränkung zu sein. Tatsächlich ist Let’s Encrypt aber dahingehend konzipiert, dass es recht einfach ist, die Zertifikate regelmäßig automatisiert zu erneuern. Das Kommando

letsencrypt renew

kontrolliert alle Let’s-Encrypt-Zertifikate Ihres Rechners und erneuert alle, die in den nächsten 30 Tagen auslaufen. Es geht also nur noch darum, den Aufruf von letsencrypt renew automatisch einmal pro Woche durchzuführen. Dazu erstellen Sie mit einem Editor die Datei /etc/cron.weekly/letsencrypt mit dem folgenden Inhalt:

#!/bin/sh
# Datei /etc/cron.weekly/letsencrypt
letsencrypt renew

Jetzt machen Sie die Datei noch ausführbar:

chmod a+x /etc/cron.weekly/letsencrypt

Let’s Encrypt für Postfix und Dovecot

Die Let’s-Encrypt-Zertifikate sind grundsätzlich universell verwendbar. Da es aber üblich ist, den SMTP-Server über den Hostnamen smtp.meine-domain.de und den IMAP-Server über imap.meine-domain.de anzusprechen, müssen Sie auch für diese beiden Hostnamen Zertifikate anfordern.

Möglicherweise wird es in Zukunft letsencrypt-Plugins geben, die sich auch um die Konfiguration der Zertifikate kümmern. Momentan ist dazu ein wenig Handarbeit erforderlich. Damit Postfix und Dovecot die Zertifikate nutzen, müssen Sie die folgenden Änderungen in den Konfigurationsdateien durchführen:

# Datei /etc/postfix/main.cf
...
smtpd_tls_cert_file=
  /etc/letsencrypt/live/www.meine-domain.de/fullchain.pem
smtpd_tls_key_file=
  /etc/letsencrypt/live/www.meine-domain.de/privkey.pem
# Datei /etc/dovecot/conf.d/10-ssl.conf
...
ssl = yes
ssl_cert = </etc/letsencrypt/live/www.meine-domain.de/fullchain.pem
ssl_key  = </etc/letsencrypt/live/www.meine-domain.de/privkey.pem

Damit die Änderungen wirksam werden, starten Sie Postfix und Dovecot neu:

service postfix restart
service dovecot restar

PS: Ich gehe hier davon aus, dass Sie Postfix und Dovecot so konfiguriert haben, dass Dovecot die SMTP-Authentifizierung für Postfix übernimmt. Eine Anleitung finden Sie z.B. hier.

Quellen

Viewing all 274 articles
Browse latest View live