Statische IP + DNS-Settings in CentOS 6

Muss man auch erstmal hinbekommen :) So funktionierts:

Hinweis: Ich gehe hier vom Netzwerkadapter eth0 aus!

Erstmal die /etc/sysconfig/network-scripts/ifcfg-eth0 bearbeiten:

DEVICE=eth0

HWADDR=”macadresse hier eintragen”

ONBOOT=yes

NETWORK=192.168.0.0

BROADCAST=192.168.0.255

NETMASK=255.255.255.0

IPADDR=192.168.0.112

USERCTL=no

Die Werte müsst ihr natürlich entsprechend eurer Netzwerkkonfiguration ersetzen.

Wenn ihr nun euer Netzwerk neustartet, wird kein Gateway und kein DNS-Server gefunden, wodurch ihr keine Verbindung zum Internet habt. Also weiter:

/etc/resolv.conf (diese muss evtl. angelegt werden, war bei mir zumindest so. Ich bin mir nicht sicher, ob man sie wirklich noch braucht, aber das kann ja mal jemand rausfinden):

search meincoolerdomainname.local

domain meincoolerdomainname.local

nameserver 192.168.0.1

 

Eine Domain müsst ihr nicht zwangsweise angeben, ist allerdings möglich. Die Nameserver-IP einfach entsprechend abändern (sofern ihr keinen separaten DNS habt, sollte das die Router-IP sein).

Zu guter Letzt wird noch das Gateway festgelegt, und zwar in /etc/sysconfig/network:

NETWORKING=yes

HOSTNAME=meincoolerhost.meincoolerdomainname.local

GATEWAY=192.168.0.1

Hier auch einfach wieder entsprechend die Werte anpassen!

Danach einmal den Netzwerkadapter neustarten:

ifdown eth0

ifup eth0

Und schon könnt ihr das Ergebnis, bspw. via “ping google.de” überprüfen!

AppleTV 2 + XBMC: Dolby Digital 5.1 funktionsfähig machen

Wer von euch das XBox Media Center auf dem AppleTV 2 verwendet und sich wundert, warum trotz AC3 5.1 vom – per SPDIF angeschlossenen – Receiver kein Dolby Digital 5.1-Signal empfangen wird, dem kann ich helfen :)

Ich hatte das Problem, dass ich, nach Aktivieren von “Receiver unterstützt AC3″ in den XMBC-Einstellungen, nur die s.g. “digital statics” gehört habe, sprich Störgeräusche anstatt Sound… Die Lösung ist relativ trivial: In den Einstellungen des AppleTV (also im iOS) muss hierzu einfach die Option “Audio-Modus” (oder Audio-Einstellungen oder wie auch immer) von “Auto” auf “16-bit” geändert werden. Dieser Modus wird laut Apple zur Kompatiblität mit manchen älteren Receivern benötigt.

Was funktioniert und was nicht

Der letzte Teil des PowerMac G5 Casemod-Berichts steht noch aus, allerdings wollte ich hier ein kurzes Update geben, wie der Stand ist:

  • ATX-Schiene sitzt – Sprich Hardware lässt sich einbauen und das Problemlos
  • Power-On-Button funktioniert (umgelötet)
  • DVD-Laufwerk (Originalteil G5) funktioniert – Problem mit der Öffnungsmechanik ist behoben
  • Netzteilaussparung an der oberen Trennplatte passt, das Netzteil ist allerdings momentan noch mit Teppichklebeband befestigt :)
  • Kaltgerätekabelverlängerung (intern) zum Verlegen des Stormanschlusses an den Original-Ausgang
  • Wärmeentwicklung hält sich in Grenzen, das System läuft dauerhaft stabil
  • Der Geräuschpegel ist akzeptabel, trotz Zusatzlüfter
  • Der Festplatten-Einschub vom PowerMac wurde nach unten verlegt (dort wo in einem normalen ATX-Netzteil auch die Festplatten werden)
Was noch zu tun ist:
  • Netzteil richtig befestigen
  • Derzeit ist nur Verschluss für die Gehäusewand installiert, ist etwas Frickelarbeit
  • Front-USB und FireWire zum laufen bekommen (warscheinlich nicht mit dem Originalbauteil sondern Umbau für internen USB-Female-Anschluss)
  • Restliche Halterungen für Seitenwand einbauen
  • Festplatten-Einschub befestigen (liegt nur auf im Moment)
  • Kabel sauber anordnen (teilweise werden noch Verlängerungen benötigt, da zu kurz)
In den nächsten Tagen werde ich den noch fehlenden Artikel für den Umbau des Gehäuses veröffentlichen (dieser ist etwas länger :) ).

Umstellung auf WordPress

Somit wäre dann auch mein altes Blog basierend auf dem Fuel Framework gegen WordPress ausgetauscht. Leider nur schweren Herzens, denn als ich mir den Code von WordPress zum ersten Mal angeschaut habe, ist mir schlecht geworden :-)

Die UI ist allerdings ganz nett, es hat SEO-Features und nachdem ich eh nichts am Unterbau machen will, kann mir der Code auch eigentlich egal sein.

Ich werde demnächst noch ein paar Fotos von mir und der Welt machen und diese als Header-Grafiken einbinden. Stay tuned :)

Tutorialreihe: To-Do-Applikation mit Fuel

Einleitung

In diesem Tutorial möchte ich euch das fantastische Fuel Framework etwas näher bringen. Bitte lasst euch von dem Wort “Framework” nicht abschrecken, es soll nämlich auch welche geben, die die Arbeit erleichtern anstatt zu erschweren. Bevor ich in der Versionreihe 0.9 auf Fuel gestoßen bin, habe ich diverse andere Frameworks ausprobiert, darunter auch CodeIgniter und das Zend Framework. Wärend allerdings bei dem einen der Code unter aller Kanone ist, braucht man für das andere einen vierzehntägige Vollzeit-Workshop um es halbwegs benutzen zu können – beides meiner Meinung nach nicht der optimale Weg. Ich möchte ein Framework herunterladen, installieren, evtl. minimal konfigurieren und dann mit der Implementierung der eigentlichen Anforderung beginnen können – das ist genau das, was Fuel anbietet.

Anforderungen

Ich setze an dieser Stelle mal “erweiterte Amateur-Kenntnisse” im Umgang mit PHP und über die Funktionsweise von MVC-Frameworks im allgemeinen und deren Aufgaben voraus. Dies impliziert natürlich auch die Archiktektur und Funktionsweise des MVC. Außerdem solltet ihr wissen, was ein ORM ist und wie er grundlegend funktioniert. Zur Bearbeitung dieses Tutorials solltet ihr ein Unix-basiertes System verwenden denn ich werde zwecks Anschaulichkeit alle Arbeitsschritte auf der Konsole machen. Dementsprechend solltet ihr auch grundlegend mit einem Linux-System umgehen können.

Natürlich muss auch ein Workspace vorhanden sein, sprich ein installierter und funktionierender LAMP-Stack (MySQL >= 5.0, PHP >= 5.3), der in meinem Fall via http://localhost/ aufrufbar ist, meine Quellen liegen in /var/www/. Falls ihr Ubuntu (>= 11.04), könnt ihr hier nachschauen, wie man relativ einfach einen LAMP-Stack installiert.

Aufgabenstellung

Wir wollen ein kleines To-Do-Portal umsetzen: Es sollen sich Benutzer registrieren können, die in einem privaten Bereich eigene To-Dos verwalten können.

Planung

Um die ganze Sache so einfach wie möglich zu halten, beschränke ich mich hierbei auf das Wesentliche: Wir haben zwei Entitäten: Benutzer und To-Do-Einträge. Benutzer haben eine ID, einen Benutzernamen, eine E-Mail-Adresse und ein Passwort, ein To-Do-Eintrag hat ebenfalls eine ID, darüber hinaus aber auch noch die Benutzer-ID und einen Beschreibungstext. Mehr brauchen wir nicht, könnte man aber dazubauen – beispielsweise Prioritäten für To-Dos oder verschiedene Listen für jeden Benutzer.

Fuel Framework installieren

Zuerst brauchen wir das Fuel Framework. Ich für meinen Teil bevorzuge die Oil-Methode (oil ist das CLI-Programm von Fuel, mit dem diverse Aufgaben bewältigt werden können, dazu später mehr). Ihr solltet sicherstellen, dass das php-cli-Paket sowie git (in manchen Distributionen git-core) installiert ist. Los gehts:

curl get.fuelphp.com/oil | sh

Per curl wird nun der oil-Installer herunter geladen und danach ausgeführt. Dieser installiert das eigentlich oil nun unter /usr/bin. Dazu werdet ihr via sudo nach eurem Benutzerpasswort gefragt.

~$ curl get.fuelphp.com/oil | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   244  100   244    0     0    691      0 --:--:-- --:--:-- --:--:--  2033
[sudo] password for xyz:

Nun ist oil installiert. Wir wechseln nun in unser www-Root-Verzeichnis und erstellen eine Fuel-Applikation:

:$ cd /var/www/
/var/www$ oil create todo

Git fängt nun an, den kompletten Quellcode aus dem Repository von Fuel zu kopieren. Der Output sieht etwa so aus:

/var/www$ oil create todo
Cloning into ./todo...
remote: Counting objects: 14105, done.
remote: Compressing objects: 100% (4898/4898), done.
remote: Total 14105 (delta 9630), reused 13253 (delta 8975)
Receiving objects: 100% (14105/14105), 2.06 MiB | 299 KiB/s, done.
Resolving deltas: 100% (9630/9630), done.
Submodule 'docs' (git://github.com/fuel/docs.git) registered for path 'docs'
Submodule 'fuel/core' (git://github.com/fuel/core.git) registered for path 'fuel/core'
Submodule 'fuel/packages/auth' (git://github.com/fuel/auth.git) registered for path 'fuel/packages/auth'
Submodule 'fuel/packages/email' (git://github.com/fuel/email.git) registered for path 'fuel/packages/email'
Submodule 'fuel/packages/oil' (git://github.com/fuel/oil.git) registered for path 'fuel/packages/oil'
Submodule 'fuel/packages/orm' (git://github.com/fuel/orm.git) registered for path 'fuel/packages/orm'
Submodule 'fuel/packages/parser' (git://github.com/fuel/parser.git) registered for path 'fuel/packages/parser'
Cloning into docs...
remote: Counting objects: 4824, done.
[...]
Submodule path 'fuel/packages/parser': checked out 'ab640352cfd6b9ba09eec4ea357ff313998f3555'
	Made writable: /var/www/todo/fuel/app/cache
	Made writable: /var/www/todo/fuel/app/logs
	Made writable: /var/www/todo/fuel/app/tmp
	Made writable: /var/www/todo/fuel/app/config

Wenn dieser Vorgang abgeschlossen ist, solltet ihr einen Ordner haben, der etwa so aussieht:

todo/
├── CHANGELOG.md
├── docs
├── fuel
├── oil
├── public
├── README.md
└── TESTING.md

Verzeichnis-Aufbau von Fuel

Relevant sind für uns die Ordner “fuel” und “public”. Letzteres ist das für den Webserver zugängliche Verzeichnis, öfters auch mal mit “htdocs” benannt, es kann beliebig umbenannt werden, ich lasse an dieser Stelle alles mal so, wie es ist. Im Ordner “fuel” findet ihr drei Unterordner:

todo/fuel/
├── app
├── core
├── LICENSE
└── packages

Unter “core” liegt Fuel selbst samt seinen Addons in “packages”. Unsere Applikation liegt unter “app”, welches wiederum so aussieht:

todo/fuel/app
├── bootstrap.php
├── cache
├── classes
├── config
├── lang
├── logs
├── migrations
├── modules
├── tasks
├── tmp
├── vendor
└── views

im Ordner classes/controller/ werden wir unsere Controller-Logik ablegen, in classes/models/ unsere Model-Dateien. Views ist das Verzeichnis, in dem unsere Templates im PHP-Format abgelegt sind. Wenn wir nun im Browser

http://localhost/todo/public/index.php

aufrufen, solltet ihr die Fuel-Willkommensseite sehen (den “welcome”-Controller). Scheint alles funktioniert zu haben :-)

Source-Code aus der Tube

Fuel und das Kommandozeilentool oil unterstützen das so genannte Scaffolding. Dies ist eine Technik, die euch erlaubt, Applikationslogik für die grundlegenden Datenbank-Operationen CRUD (Create, Retrieve, Update, Delete) zu erzeugen, ohne dafür eine Zeile Code schreiben zu müssen. Weiterhin bietet das Framework s.g. Migrations an. Migrations sind vereinfacht gesagt DBMS-Unabhänige Datenbankdefinitionen, die es erlauben zwischen Datenbank-Ständen hoch und runter zu migrieren. Im Falle von Fuel ist es eine Klasse mit den Methoden up() und down(). Ersteres definiert z.B. neue Tabellen, die bei einem Upgrade auf die aktuelle Version angelegt werden müssen, down() bildet das entsprechende Gegentstück für ein Downgrade.

Das Scaffolding von Fuel legt uns also folgendes an:

  • eine Migration
  • das dazugehörige Model
  • einen Controller
  • Views für die entsprechenden Controller-Aktion (CRUD)

Dies lässt sich natürlich auch auf unsere To-Do-Applikation anwenden, also legen wir mit Hilfe von oil ein Scaffold an, dazu wird zuerst in das Hauptverzeichnis unsererer Applikation gewechselt:

cd /var/www/todo/

Das Scaffold für To-Dos sieht so aus:

/var/www/todo$ oil generate scaffold todos user_id:int body:string
    Creating model: /var/www/todo/fuel/app/classes/model/todo.php
    Creating migration: /var/www/todo/fuel/app/migrations/001_create_todos.php
    Creating controller: /var/www/todo/fuel/app/classes/controller/todos.php
    Creating view: /var/www/todo/fuel/app/views/todos/index.php
    Creating view: /var/www/todo/fuel/app/views/todos/view.php
    Creating view: /var/www/todo/fuel/app/views/todos/create.php
    Creating view: /var/www/todo/fuel/app/views/todos/edit.php
    Creating view: /var/www/todo/fuel/app/views/todos/_form.php
    Creating view: /var/www/todo/fuel/app/views/template.php

Relativ einfach, oder? Wie man an der Ausgabe erkennen kann, wurde alles relevante angelegt. Ihr solltet euch nun jede der Dateien einmal ansehen, um zu verstehen, wie alles funktioniert, generell ist der Code aber für einen ein wenig erfahrenen PHP-Entwickler selbsterklärend.

Wenn wir nun allerdings versuchen, unsere URL zum “todos”-Controller aufzurufen, erhalten wir eine Fehlerseite:

http://localhost/todo/public/index.php/todos/
1045!
Fuel\Core\Database_Exception [ 1045 ]: SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' (using password: YES)

Das ist nicht weiter ungewöhnlich, haben wir doch noch weder eine Datenbank konfiguriert, noch das Migrationsskript in die Datenbank eingespielt. Das müssen wir nun noch tun: Datenbankkonfiguration öffnen und die Zugangsdaten eintragen:

nano fuel/app/config/development/db.php
    'dsn'        => 'mysql:host=localhost;dbname=todo_db',
    'username'   => 'root',
    'password'   => '',

Nun muss noch das Migrationsskript in die Datenbank eingespielt werden:

/var/www/todo$ oil refine migrate
Migrated app:default to latest version: 1.

Wenn wir unsere URL nun erneut aufrufen, haben wir eine Seite, auf der wir Todos anzeigen, anlegen, bearbeiten und löschen können!

Benutzerverwaltung SimpleAuth

Fuel bietet ein Package namens SimpleAuth. Dies ist, wie der Name vermuten lässt, eine simple Implementierung einer Benutzerauthentifizierung samt ACLs und benutzerdefinierten Profilfeldern. Die letzeren zwei Funktionen werden wir allerdings nicht benutzen, sondern beschränken uns hier auf die Authentifizierung an und für sich. Zuerst muss das Package in der Applikation-Konfiguration aktiviert werden:

/var/www/todo$ nano fuel/app/config/config.php

Der Key ['always_load']['packages'] sollte hier so aussehen:

    'packages'  => array(
        'auth',
    ),

Zusätzlich müssen die SimpleAuth-Konfigurationsdateien noch aus dem Package-Ordner in den Applikationsordner kopiert werden:

/var/www/todo$ cp fuel/packages/auth/config/auth.php fuel/packages/auth/config/simpleauth.php fuel/app/config/

Der Salt zur Verschlüsslung der Passwörter in der Datei fuel/app/config/auth.php sollte aus Sicherheitsgrunden noch geändert werden.

Nun müssen wir noch eine Datenbanktabelle anlegen, nämlich die für die Benutzer:

CREATE TABLE `users` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `username` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
    `password` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
    `group` INT NOT NULL DEFAULT 1 ,
    `email` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
    `last_login` VARCHAR( 25 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
    `login_hash` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
    `profile_fields` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
    UNIQUE (
        `username` ,
        `email`
    )
);

Soweit – so gut! Jetzt brauchen wir nur noch einen User zum testen. Wir erstellen uns also eine Datei setup.php unter fuel/app/classes/controller/ und befüllen sie:

[...]
class Controller_Setup extends Controller
{
    public function action_user()
    {
        $auth = Auth::instance();
        $userid = $auth->create_user("max_mustermann", "123", "mmustermann@backport.net");

        echo "user created: " . $userid;
    }
}

Wenn wir nun im Frontend die URL

http://localhost/todo/public/index.php/setup/user

aufrufen, sollte dort stehen:

user created: 1

Prima! Wir haben nun also einen Benutzer “max_mustermann” mit dem Passwort “123″ und der E-Mail-Adresse “mmustermann@backport.net”. Den Controller könnt ihr nun wieder löschen, den brauchen wir nicht mehr.

Die Fahrkarten bitte

Als Nächstes wäre dann wohl der Login-Prozess an der Reihe. Was soll passieren? Nun – wenn wir auf

http://localhost/todo/public/index.php/todos/

navigieren, soll der geprüft werden, ob der Benutzer eingeloggt ist. Ist dies nicht der Fall, muss er auf eine Login-Seite weitergeleitet werden. Klingt einfach, fast genau so einfach ist es auch zu programmieren. Platziert werden soll dieser Code in der Methode before() unserer Controller_Todos-Klasse. Kurz zur Erklärung: Die Methoden before() und after() werden vor- und nach dem Aktionsaufruf eines Controllers ausgeführt; before() ist also der ideale Platz für unsere Prüfung.

/var/www/todo$ nano fuel/app/classes/controller/todos.php
[...]
Class Controller_Todos extends Controller_Template {

    public function before()
    {
        parent::before();

        if(!Auth::check())
        {
            Response::redirect("login");
        }
    }
[...]

Zuerst muss sichergestellt sein, dass der Code der Methode before() aus der Klasse Controller_Template (übergeordnete Klasse) noch ausgeführt wird. Die Methode Auth::check() liefert einen boolschen Wert, der angibt, ob der Benutzer eingeloggt ist. Kommt false zurück, wird der Benutzer per Response::redirect() zum Controller “login” weitergeleitet.

Nur blöd, dass es diesen Controller noch nicht gibt. Dem kann allerdings abhilfe geschaffen werden:

/var/www/todo$ oil generate controller login
    Creating view: /var/www/todo/fuel/app/views/login/index.php
    Creating controller: /var/www/todo/fuel/app/classes/controller/login.php

Via oil wird nun eine leere View und ein Controller angelegt, die wir nun befüllen können. Zuerst erstellen wir das Login-Formular:

/var/www/todo$ nano fuel/app/classes/views/login/index.php
<?php echo Form::open(); ?>
    <p>
        <?php echo Form::label('Benutzername', 'username'); ?>
        <?php echo Form::input('username'); ?>
    </p>
    <p>
        <?php echo Form::label('Passwort', 'password'); ?>
        <?php echo Form::password('password'); ?>
    </p>
    <div>
        <?php echo Form::submit(); ?>
    </div>
<?php echo Form::close(); ?>

Das sollte relativ selbsterklärend sein, eine genaue Referenz der Methoden kann der Dokumentation entnommen werden. Nun müssen wir im Controller prüfen, ob der Abschicken-Button geklickt wurde. Ist dem so, dann sollen die Zugangsdaten geprüft werden und der Benutzer eventuell eingeloggt und zur Todo-Seite weitergeleitet werden.

/var/www/todo$ nano fuel/app/classes/controller/login.php
<?php
[...]
class Controller_Login extends Controller_Template {

    public function action_index()
    {
        if("POST" == Input::method())
        {
            $username = Input::post("username");
            $password = Input::post("password");
            $login = Auth::instance()->login($username, $password);

            if($login)
            {
                Response::redirect("todos");
            }
            else
            {
                throw new Exception("Zugangsdaten falsch!");
            }
        }

        $this->template->title = 'Login » Index';
        [...]

Das sollte auch alles relativ selbsterklärend sein, aber nochmal in Kurzform: Zuerst wird geprüft, ob das Formular abgeschickt wurde. Falls ja, wird der eingegebene Benutzername und das Passwort aus dem Request geholt und per Auth::instance()->login() der Login durchgeführt. Ist dieser erfolgreich, wird der Benutzer auf dem Controller “todos” weitergeleitet, andernfalls wird eine Exception geworfen (das könnt ihr ja noch verschönern).

Wenn ihr das ganze nun testet, sollte der Login mit den – im vorhergehenden Schritt angelegten – Zugangsdaten funktionieren.

Jeder nur seins

Nun sollte natürlich jeder Benutzer nur die To-Dos sehen, die er selbst angelegt hat. Dazu ist nur eine kleine Modifikation an der action_index()-Methode des Todo-Controllers von nöten:

/var/www/todo$ nano fuel/app/classes/controller/todos.php
public function action_index()
{
	$user = Auth::get_user_id();

	$data['todos'] = Todo::find_by("user_id", $user[1]);
        $this->template->title ="Todos";
	[...]

Auth::get_user_id() gibt ein Array zurück, welches folgender Maßen aussieht:

array(2) {
  [0]=>
  string(10) "SimpleAuth"
  [1]=>
  int(1)
}

Der Key 1 beinhaltet die eigentliche User-ID, sodass diese benutzt werden kann, um nur Einträge mit der entsprechenden user_id zu holen.

Fazit

Wie ihr seht, ist es mit dem Fuel Framework nicht schwer, relativ schnell komplexe Applikationen zu entwickeln. Gerade durch oil und die Erstellung von Teilen der Programmlogik via Template kann der Arbeitsaufwand minimiert werden. Doch selbst wenn man noch alles von Hand schreibt, bietet Fuel mit seiner Vielzahl an einfach benutzbaren APIs viel Komfort beim Programmieren.

Fortsetzung folgt

Die Registrierung, Verschönerung, eventuelle Usability-Anpassungen sowie Sicherheitsmaßnahmen werden in diesem Tutorial nicht behandelt. Dafür werde ich in Kürze einen separaten Artikel verfassen.

Mit Warp-Geschwindigkeit

Nachdem die Festplatte meines MBP schon seit mehreren Monaten komische Geräsche gemacht hat und ich mir etwas mehr Geschwindigkeit von einer SSD versprach, habe ich mir vor Kurzem dann auch eine solche zugelegt: die Vertex 2 von OCZ sollte es sein. Das 60GB-Modell liegt preislich bei knapp 70€ und zählt somit eher zu den günstigen Solid State-Platten.

Der Einbau ging erstaunlich leicht von Statten: Die Schrauben auf der Unterseite des Laptops lösen und dann noch zwei im Inneren, und schon konnte die Festplatte ausgetauscht werden. Alles in allem etwa eine Sache von 10 Minuten.

xx

Kurz: Ich bin begeistert. Wo die Ladezeit bestimmter Applikationen teilweise vorher im zweistelligen Sekundenbereich lag, öffnen sich nun die meisten Programme innerhalb von kürzester Zeit. Den Geschwindigkeitsvorteil möchte man schon nach sehr kurzer Zeit nicht mehr missen.