Für einen meiner Kunden betreue ich eine Anwendung namens “DUPL”. Die Anwendung besteht aus verschiedenen Teilen, u.a.
Für die Betreuung brauche ich
Bislang wurde das durch eine Mischung aus Standard-Unix-Zugriffsrechte und Cronjobs erledigt. Mit ACLs müßte das wesentlich eleganter umzusetzen sein.
Der Tomcat von DUPL läuft unter einem eigenen Benutzer “tomcat-dupl” in einer eigenen Gruppe “tomcat-dupl”. Er hat ein Arbeitsverzeichnis /data/dupl. In diesem Arbeitsverzeichnis legt er Dateien und Verzeichnisstrukturen an. Die Struktur unterhalb des Arbeitsverzeichnisses sieht dann beispielsweise so aus:
Mein Wartungsbenutzer ist unabhängig vom Tomcat-Benutzer: Er hat den Namen “uli” und gehört nicht der Tomcat-Gruppe an, sondern nur der Gruppe “staff”.
Die Wartungstätigkeiten erfordern die Möglichkeit:
Beim bisher verwendeten traditionellen Ansatz wird:
Das Arbeitsverzeichnis /data/dupl dem Benutzer “tomcat-dupl” und der Gruppe “staff” zugeordnet:
chown tomcat-dupl.staff /data/dupl
Die Zugriffsrechte so geändert, dass sowohl der Benutzer als auch die Gruppe vollen Lese- und Schreibzugriff hat:
chmod 775 /data/dupl
Zusätzlich wird noch das “SETGID”-Bit gesetzt, so dass alle Dateien und Verzeichnisse der Gruppe “staff” zugeordnet werden:
chmod g+s /data/dupl
Die UMASK für den Tomcat-Benutzer und meinen Wartungsbenutzer wird auf “002” gesetzt, so dass neu angelegte Dateien und Verzeichnisse per Standard für die Gruppe beschreibbar sind:
umask 002
Mit diesen Einstellungen kann ich alle Dateien, die der Tomcat unterhalb von /data/dup anlegt, problemlos lesen und schreiben. Das ganze funktioniert auch für alle Unterverzeichnisse und darin enthaltene Dateien.
Blöd wird’s, wenn ich mit meinem Benutzer darin rumwerkle und den
UMASK-Eintrag nicht richtig gesetzt habe. Wenn ich bspw. um umask 022
in /data/dup neue Dateien oder Verzeichnisse anlege, dann hat
der Tomcat nur Lesezugriff und keinen Schreibzugriff.
Um die Auswirkungen von solchen Aktionen in Grenzen zu halten gibt es einen regelmässig ausgeführten CRONJOB, der für alle Dateien und Verzeichnisse die Schreibrechte für die Gruppe setzt, also etwas wie:
1
|
|
Mit ACLs kann man die Sache zuverlässiger in den Griff bekommen, die Rechte hängen dann nicht mehr von der UMASK ab.
setfacl -m g:staff:rwx /data/dupl
setfacl -m g:tomcat-dupl:rwx /data/dupl
setfacl -d -m g:staff:rwx /data/dupl
setfacl -d -m g:tomcat-dupl:rwx /data/dupl
setfacl -R -m g:staff:rwx /data/dupl
setfacl -R -m g:tomcat-dupl:rwx /data/dupl
setfacl -R -d -m g:staff:rwx /data/dupl
setfacl -R -d -m g:tomcat-dupl:rwx /data/dupl
Die Traces von Oracle 11G werden abgelegt unter /app/oracle/admin/oradba/udump.
Per Standard habe ich keinen Lesezugriff auf die Traces. Eine einmalige Ausführung
von chmod o+r ...
bringt nichts, weil Oracle 11G dort immer wieder neue Dateien
erzeugt, deren Zugriffsrechte ebenfalls geändert werden müssen.
Auch hier kann man mit ACLs für die Lösung sorgen:
setfacl -R -m g:staff:r /app/oracle/admin/oradba/udump
setfacl -m g:staff:rx /app/oracle/admin/oradba/udump
setfacl -R -d -m g:staff:r /app/oracle/admin/oradba/udump
Ein privates Git-Repository mit einer langen Git-Versionsgeschichte soll bspw. auf GitHub veröffentlicht werden. Üblicherweise erscheint das Repository dann inklusive kompletter Versionsgeschichte.
Ziel des hier beschriebenen Verfahrfens ist:
Unsere Ausganglage ist diese:
1 2 3 |
|
1 2 3 4 |
|
Der für mich einfachste Ablauf ist dieser:
git branch -m master ancient-history
git checkout --orphan master
git commit -m "Initial commit"
git log --oneline master
git log --oneline master ancient-history
git clone git/sandbox.git
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Danach sichten, ob der Zweig in Subversion angekommen ist:
1 2 |
|
Sieht gut aus, es gibt den “subgit-branch”!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Sieht gut aus, Subversion “merkt”, dass nicht zu tun ist.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
1 2 3 4 5 |
|
Das Verzeichnis sieht gut aus!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Das Verzeichnis sieht gut aus!
1 2 3 4 5 |
|
Die Arbeit mit Zweigen und auch die Zusammenführung funktioniert recht problemlos. Zusammenführungen in Git werden auch in Subversion erkannt und umgekehrt.
]]>Auf dem Server läuft ein Ubuntu-12.04, weitgehend in Standardkonfiguration. SSH habe ich auch erstmal unverändert belassen. Für meinen Benutzer habe ich die Anmeldung mittels “public/private key” eingerichtet, die funktioniert auch – ich muß beim SSH-Zugriff das Benutzerkennwort nicht eingeben und lande direkt auf der Kommandozeile.
Unschön ist nur die lange Dauer, bis die Kommandozeile erscheint.
Es zeigt sich, dass die Ursache die Wandlung von IP-Adressen nach Hostnamen ist. Bei der SSH-Anmeldung versucht der Server üblicherweise, die IP-Adresse des Heimrechners umzuwandeln in den Namen dieses Rechners. Das funktioniert für mein Heimnetz oftmals nicht richtig und läuft in eine Zeitüberschreitung. Dies führt zu der Wartezeit.
Ich schalte die Wandlung von IP-Adressen nach Hostnamen einfach ab. Dazu modifiziere ich die Datei “/etc/ssh/sshd_config” wie folgt:
1 2 3 4 5 6 7 8 |
|
Zur “Sicherheit” starte ich den SSHD noch neu mit /etc/init.d/ssh restart
und kontrolliere die SSH-Anmeldegeschwindigkeit: Alles gut!
1 2 |
|
1 2 3 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
1
|
|
Mit den üblichen Git-Kommandos!
Beim lokalen Git-Commit wird nur die “Kopie” im Verzeichnis “sandbox” aktualisiert!
1
|
|
Beim zentralen Git-Commit wird das zentrale Git-Repository “…/git/sandbox.git” aktualisiert und auch das Subversion-Repository:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Hier der Ablauf, wenn man einen Konflikt mit Subversion “provoziert”. Änderung in Subversion durchführen:
1 2 |
|
Nun die gleiche Datei in Git ändern:
1 2 3 4 5 6 |
|
SubGit sieht schonmal sehr vielversprechend aus. Es ist sehr einfach einzurichten und funktioniert dem ersten Eindruck nach tadellos. Für mich zu klären sind noch die Lizenzbedingungen sowie der Einsatz “im Team”.
Leider generiert besagtes Kommando seit neuestem zusätzliche Ausgaben auch wenn alles OK ist, das Skript läuft dann auf einen Fehler.
Nun brauche ich eine Möglichkeit zum intelligenten Filtern des Inhaltes der Variablen!
Mit GREP schaffe ich’s recht einfach, alle Ausgaben, die mit “Starten” beginnen, zu entfernen:
# Funktion zum Ausfiltern aller Zeilen, die einem Muster entsprechen
filterOut () {
grep -v "^Starten "
}
# Testdaten
AA="$(cat <<EOF
Starten von Replicate.sql
Replicate.sql running
Replicate.sql finished
EOF
)"
# Filterung durchführen
echo "${AA}"|filterOut
# Ausgaben:
# Replicate.sql running
# Replicate.sql finished
Leider gibt es kein einfaches Muster, um alle ungewünschten Ausgaben rauszuwerfen. Wir brauchen mehrere Muster!
# Funktion zum Ausfiltern aller Zeilen, die einem von mehreren Mustern entsprechen
filterOut () {
grep -v \
-e "^Starten " \
-e "sql finished$"
}
# Testdaten
AA="$(cat <<EOF
Starten von Replicate.sql
Replicate.sql running
Replicate.sql finished
EOF
)"
# Filterung durchführen
echo "${AA}"|filterOut
# Ausgaben:
# Replicate.sql running
Das “geerbte” Projekt läuft unter AIX 6.1. Schön wär’s, wenn obiges Konstrukt auch dort funktioniert. Ein kurzer Quercheck zeigt: Ja, GREP verhält sich unter AIX genauso.
]]>Umgesetzt habe ich das ganze mit einem SSH-Konto auf meinem Fileserver.
1 2 3 4 5 6 |
|
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 7 |
|
Ich verwende Thunderbird zusammen mit Truecrypt. Ich habe eine USB-Stick. Auf dem liegt eine Truecrypt-Partition. Von dieser wird Thunderbird gestartet.
1 2 3 4 5 6 7 8 9 10 |
|
Zunächst muß die Truecrypt-Partition ausgehängt werden, damit sie für Korrekturen frei ist.
1 2 |
|
Erster Versuch: Ausführung von fsck.vfat. Leider kein Erfolg, das Dateisystem wird nicht korrigiert!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Mit der Option ‘-a’ sollte es eigentlich klappen. Leider gibt’s am Ende die Fehlermeldung “Unable to create unique name”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Als nächstes führe ich fsck.vfat mehrfach mit der Option ‘-r’ aus. Bis auf die Sache mit dem Boot Sector bestätige ich einfach jede Änderung. Auffällig: Beim zweiten Durchlauf werden neue Fehler gefunden und korrigiert. Erst beim dritten Durchlauf gibt es keinen Fehler mehr.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 |
|
Schlußtest nochmal mit der Option ‘-a’: Kein Fehler mehr vorhanden!
1 2 3 4 5 6 7 |
|
1
|
|
… klappt nun im Schreiblese-Modus!
Nach den Korrekturen an der Truecrypt-Partition startet Thunderbird leider nicht mehr richtig: Ich werde aufgefordert, ein neues Konto anzulegen.
Wenn ich mir direkt das Adressbuch anzeigen lasse, dann sehe ich dort noch meine Einträge – gut!
In meinem Profilverzeichnis /media/truecrypt1/thunderbird-uli gibt es eine Datei “prefs.js”. Diese sieht allerdings sehr klein aus. Sie hat nur eine Größe von grob 3KB.
Ich finde noch eine Datei “prefs-1.js” vom Vortag, die hat eine Größe von grob 60 KB.
cp prefs-1.js prefs.js
Zur Entwicklung des im Projektrahmen zu erstellenden Programms benötige ich ein JDK. Das Einspielen auf dem Notebook gestaltet sich schwierig, denn ich habe dort keine Administratorrechte und Oracle’s JDK benötigt eben diese. Schöner Mist. Nachfolgend eine Beschreibung, wie ich mir beholfen habe. Ich benötige dazu einen Linux-Rechner und einen USB-Stick.
Auf meinem Linux-Rechner ist Ubuntu-12.04 installiert. Zusätzlich benötige ich Wine. Dieses wird schnell nachinstalliert mit
sudo apt-get install wine
Die Installation hat bei mir zunächst nicht geklappt – vermutlich weil ich auch VirtualBox auf dem Linux-Rechner habe. In einem LXC-Container ging’s problemlos.
Danach:
wine ./jdk-7u40-windows-i586.exe
zip
)javac -version
–> javac 1.7.0_40Der Aufruf vom Java-Kompiler klappt – ich bin zufrieden!
]]>1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Aus den Ausgaben kann man diese Zuordnung erkennen:
Die Platten-IDs sollten am besten auch auf den jeweiligen Einbaurahmen geschrieben werden, damit es zu keinen Verwechslungen kommen kann.
Die Einbaurahmen werden mit den Platten-IDs beschriftet, damit beim Ausfall einer Platte schnell der richtige Rahmen gefunden werden kann. Beim mir ist “sda” ganz links, “sdd” ganz rechts. Die Platten-IDs sind auch auf den Platten aufgedruckt, und zwar bspw. wie folgt:
S/N: WCC1T0770511
Der Aufdruck sollte als Quercheck für die Beschriftung dienen!
1 2 3 4 5 6 |
|
Nach dem Anlegen sollte der Status kontrolliert werden:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Wichtig: Alles “ONLINE”, keine Fehler und “raidz1-0” muß angezeigt werden!
Einen Plattenausfall erkennt man mit “zpool status”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Beim Ausfall sind diese Aktionen nötig:
sudo zpool replace zfsdata {old} {new}
$ sudo zpool replace zfsdata \ scsi-SATA_WDC_WD30EFRX-68_WD-WCC1T0770511 \ scsi-SATA_WDC_WD30EFRX-68_WD-WCC1T0774712
sudo zpool status
Zur Lösung der letzten beiden Probleme gibt es nun die Idee, einen eigenen Proxy-Server zu betreiben, der dann die Anmeldung am “richtigen” Proxy-Server übernimmt und der den User-Agent auf geeignete Werte setzt.
Den Proxy-Server habe ich in Java implementiert und im Rahmen meiner “Mini-Tools” auf GitHub abgelegt. Zu finden ist der Proxy-Server hier: Forward-Proxy.
Der eigentliche Kern des Proxy-Servers ist recht klein – die meisten Zutaten liefert das Projekt Jetty. Konkret habe ich hiervon verwendet:
Zur Kompilierung des Projektes verwende ich Gradle. Von mir selbst stammen ein paar Ergänzungen, die
Das Bauen des Projektes ist denkbar einfach, sofern ein JDK7 installiert und im PATH verfügbar ist:
../gradlew
(… oder unter Windows: ..\gradlew
)Danach gibt es die beiden Dateien
Sie können direkt von der Shell aus ausgeführt werden.
Getestet habe ich den neuen Proxy-Server mit einem einfachen Gradle-Projekt:
Konfigurationsdatei “forward-proxy.properties” für den Forward-Proxy:
proxyPort = 8888
parentProxyHost = 192.168.178.47
parentProxyPort = 3128
parentProxyUser = uli
parentProxyPassword = xxxxxx
replaceHeaders = User-Agent
User-Agent = InternetExploder
Start vom Forward-Proxy:
./forward-proxy*.sh
gradle.properties:
systemProp.http.proxyHost=localhost
systemProp.http.proxyPort=8888
Gradle-Projekt auspacken und neu bauen mit
./gradlew --refresh-dependencies
# Windows: .\gradlew --refresh-dependencies
Mit diesem Befehl werden Kompilierung und Übersprungen:
fakeroot debuan/rules binary
Innerhalb von wenigen Sekunden weiß ich so, ob die Korrekturen richtig waren oder ob ich noch weitere Dinge ändern muß. Wenn das Kommando durchläuft, führe ich idR. nochmals
dpkg-buildpackage
aus um das Paket komplett neu zu bauen und zu paketieren.
]]>1 2 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
1
|
|
1 2 3 4 |
|
1
|
|
Mit den obigen Vorbereitungen kann ich den neuen Proxy-Server nun mittels http://{hostname-der-vm}:3128 ansprechen.
Mit diesen Befehlen kann die effektive Konfigurationsdatei ermittelt werden. Die vielen Kommentare werden dabei ausgefiltert:
1
|
|
Die effektive Squid-Konfiguration sieht ohne Kommentare dann so aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
Auf der Projektseite den Knopf “Fork” anwählen:
Folgeseiten “durchklicken”
Gespaltenes Projekt kopieren mit: git clone <clone-url-s>
, also
im konkreten Fall git clone git@github.com:uli-heller/moxie.git
:
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 6 |
|
1 2 3 4 5 6 |
|
Gelegentlich will man die Änderungen des Original-Projektes
in das abgespaltete Projekt einarbeiten. Vor der Einarbeitung
muß die Kopie des Original-Projektes aktualisiert worden sein
(git fetch upstream
).
Hier der Ablauf, wenn am Original-Projekt zwischenzeitlich nur eigene Pull-Requests eingearbeitet wurden. Die Aktualisierung läuft in diesem Falle völlig schmerzfrei!
1 2 3 4 5 6 7 8 |
|
Wenn am Original-Projekt zwischenzeitlich auch andere Änderungen
gemacht wurden, so kommt es gelegentlich zu Konflikten beim
Einarbeiten. Die Konflikte können mit git mergetool
aufgelöst
werden. Wichtig: Vor dem abschließenden git commit
sollte
der neue Stand ausführlich getestet werden!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Hierbei müssen diese Ersetzungen vorgenommen werden:
1
|
|
http://www.networkworld.com/community/blog/9-linux-podcasts-you-should-follow
]]>In diesem Artikel beschreibe ich, wie ich die Themenwolke eingerichtet habe.
Herunterladen von GitHub – ZIP-Datei, meine Kopie liegt hier.
1 2 3 |
|
In der Konfigurationsdatei von Octopress müssen diese Änderungen durchgeführt werden:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Die Datei “source/categories/index.html” wird angelegt, um eine separate Seite mit allen Themen zur Verfügung zu haben. Bei meiner Variante wird oben die Themenwolke angezeigt, unten eine alphabetisch sortierte Themenliste.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Die Themenseite wird durch Änderung an “source/_includes/custom/navigation.html” in die Navigation eingebunden:
1 2 3 4 5 6 7 8 9 10 11 |
|
Ziel dieses Artikels ist die Beschleunigung des Generierungsprozesses.
Das Plugin Octopress-Gallery zur Anzeige der Fotogallerie konvertiert die Bilder automatisch in’s Thumbnail-Format. Es ist zwar ein Algorithmus eingebaut, der die Konvertierung der Bilder nur dann durchführen soll, wenn sich die Bilder geändert haben – er funktioniert aber leider nicht.
Als Konsequenz dieser Änderungen müssen noch:
Das Konvertierungsskript befindet sich auf GitHub
Die alte Konvertierung wird abgeklemmt, in dem
1
|
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Hierzu muß die Datei plugins/gallery_tag.rb angepasst werden. Wir ändern dies so, dass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
apt-get upgrade
in meinen LXC-Containern auf:
$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be upgraded:
apt apt-utils base-files gnupg gpgv libapt-inst1.4 libapt-pkg4.12 libudev0
lsb-base lsb-release udev
11 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 3752 kB of archives.
After this operation, 25.6 kB of additional disk space will be used.
Do you want to continue [Y/n]?
...
Preparing to replace udev 175-0ubuntu9.3 (using .../udev_175-0ubuntu9.4_amd64.deb) ...
Adding 'diversion of /sbin/udevadm to /sbin/udevadm.upgrade by fake-udev'
dpkg: unrecoverable fatal error, aborting:
failed to fstat previous diversions file: No such file or directory
E: Sub-process /usr/bin/dpkg returned an error code (2)
Ich denke, das Problem hängt zusammen mit der Aktualisierung des Paketes “udev”.
Zur Korrektur des Problems muß ich mehrfach diese Kommandos ausführen:
1 2 |
|
Nach zwei bis drei Durchläufen ist das Problem verschwunden.
]]>Bei der Installation als Gastsystem innerhalb von VirtualBox sind folgende Besonderheiten zu beachten:
Bei “System” muß folgendes aktiviert werden:
Mit anderen Einstellungen blieb bei mir das Gastsystem immer hängen
Für den Massenspeicher sollte nur ein IDE-Controller verwendet werden
Bei mir blieb das Gastsystem immer hängen, wenn ich einen SATA-Controller verwendet habe