Posts Tagged ‘Git’

Sonntag, 27. März 2016

Sismics Docs installieren

Als Projekt für das Oster-Wochenende habe ich mir die Installation eines Dokumentenmanagementsystems (DMS) vorgenommen. Ziel ist es, die von mir seit Jahren gescannten Einkaufsbelege sauber in einem Archiv abzulegen und die Belege anschliessend mit meiner selbstprogrammierten Buchhaltungs-Applikation (PHP/MySQL) zu verknüpfen.

Nach einem wenig erfolgsversprechenden Umweg über Alfresco (zu gross, zu komplex, beansprucht zu viele Ressourcen) landete ich schlussendlich bei Sismics Docs, auch wenn dieses in einer Übersicht quelloffener DMS aus dem Jahr 2010 nicht erwähnt wird. Die Screenshots haben mich überzeugt, die Software zu installieren und herunterzuladen.

Da ich mich nicht mit Java-Applikationen auskenne, liefere ich hier eine Installationsanleitung. Sie richtet sich an Personen, welche ausreichend Linux-Erfahrung haben, anstelle aus der Java- aber aus der PHP/MySQL-Ecke kommen.

Repository auschecken

Als erstes legen wir uns eine lokale Kopie des Git-Repositories an:

# mkdir /usr/local/bin/sismics
cd /usr/local/bin/sismics
git clone https://github.com/sismics/docs.git .

To Dock or not to Dock

Unter den Dateien des Repositories finden sich Hinweise darauf, dass der Entwickler Docker zu verwenden scheint; u.a. existieren im Wurzelverzeichnis des Repositories die Dateien Dockerfile, build.sh und run-service.sh.

Ich konnte das Teil mit Docker aber nicht zum Laufen bringen. Dies aus mehreren Gründen:

i686

Der kräftigere meiner beiden Linux-Server, welcher im Elternhaus läuft, hat Debian i686 installiert, ein 32-bit Linux. Docker erfordert x86_64 (64-bit). Ein forciertes Upgrade tönt nach digitalem Selbstmord.

Die Bit-Architektur überprüfen kann man dies mit folgendem Befehl:

$ uname -m
x86_64

Docker installieren

Der Intel NUC, welcher in unserer Mietwohnung im Netzwerk hängt, hat ein x86_64 Linux am Laufen. Deshalb führte ich dort die Installation gemäss der offiziellen Anleitung aus.

Vorgängig musste ich noch herausfinden, welche Debian-Version ich installiert hatte:

# lsb_release -da
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 8.3 (jessie)
Release:	8.3
Codename:	jessie

Quelle: Check what Debian version you are running on your Linux system

Jessie! Anschliessend folgte ich der offiziellen Anleitung:

# apt-get install apt-transport-https ca-certificates
# apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
# echo "deb https://apt.dockerproject.org/repo debian-jessie main" > /etc/apt/sources.list.d/docker.list
# apt-get update
# apt-get install docker-engine
# service docker start
# docker run hello-world

Bingo, Docker läuft.

Image nicht gefunden

Leider funktioniert die Generierung des Images für das Sismics Docs nicht:

# cd /usr/local/bin/sismics
# docker build -t sismics:0.1 .
Sending build context to Docker daemon 14.35 MB
Step 1 : FROM sismics/debian-java7-jetty9
Pulling repository docker.io/sismics/debian-java7-jetty9
Error: image sismics/debian-java7-jetty9 not found

Mit dem Switch -t definiert man das Paket und den Tag (vgl. Docker — build.

*seufz* Okey, dann halt kein Docker.

Manuelle Installation

Nun gut, da wir den Docker-Weg nicht beschreiten können, verlassen wir den Intel NUC und wenden uns wieder dem kräftigeren Server zu.

Pakete

Damit man schon nur die Testumgebung des DMS hockriegt, benötigt man folgende Pakete:

# apt-get install maven tesseract-ocr openjdk-7-jdk

Testinstallation bauen

Sobald die Pakete auf dem Rechner liegen, bauen wir uns die Testinstallation:

# cd /usr/local/bin/sismics/docs-parent
# mvn clean -DskipTests install
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Docs Parent ........................................ SUCCESS [  7.114 s]
[INFO] Docs Core .......................................... SUCCESS [01:37 min]
[INFO] Docs Web Commons ................................... SUCCESS [ 47.086 s]
[INFO] Docs Web ........................................... SUCCESS [ 30.833 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 03:02 min
[INFO] Finished at: 2016-03-27T09:52:29+00:00
[INFO] Final Memory: 34M/94M
[INFO] ------------------------------------------------------------------------

Testinstallation starten

Nun starten wir die Testinstallation, um zu sehen, ob alles wie gewünscht funktioniert:

# cd /usr/local/bin/sismics/docs-web
mvn jetty:run
...
[INFO] Started ServerConnector@b40c2f{HTTP/1.1}{0.0.0.0:8080}
[INFO] Started @23372ms
[INFO] Started Jetty Server

Sobald diese Anzeige erscheint, können wir mit einem Web-Browser auf den Applikationsserver zugreifen:

10.1.2.3:8080/docs-web/src/

Das Standardpasswort des Administrator-Kontos lautet admin, wie eine Suche durch den Quellcode offenbart:

$ ack passw
...
docs-core/src/main/java/com/sismics/docs/core/constant/Constants.java
19:     * Administrator's default password ("admin").
...

Java Advanced Imaging

Die Web-Oberfläche funktioniert, man kann Dateien hochladen — doch ausgerechnet das erste PDF produzierte folgende Fehlermeldung im Log der Applikation:

Cannot read JPEG2000 image: Java Advanced Imaging (JAI) Image I/O Tools are not installed

Diese Tools installiert man sich folgendermassen:

$ cd /tmp
$ wget "https://install-java-jai-imageio.googlecode.com/files/install-java-jai-imageio"
# bash /tmp/install-java-jai-imageio

Quelle: Install Java Advanced Imaging ImageIO Tools on a Linux Machine

ACHTUNG: Bitte den Inhalt aller aus dem Netz heruntergeladenen Bash-Scripts gründlich prüfen, bevor man sie unter dem root-Account ausführt.

Weitere Pakete installieren

Rückblickendes Ziel meines Sonntagsprojekts war es, die Applikation unter dem Java-Applikationsserver Jetty persistent zum Laufen zu bringen. Hierzu bauen wir uns ein sog. war-File. Damit das auch sauber funktioniert, benötigen wir folgende Pakete:

# apt-get install nodejs npm
# ln -s /usr/bin/nodejs /usr/bin/node
# npm install -g grunt-cli

Wir sehen, ob alle nötigen Komponenten da sind, wenn folgende Befehle einen Wert zurückgeben:

$ which node
/usr/bin/node
$ which grunt
/usr/local/bin/grunt

Insbesondere das node-Binary ist zwingend nötig — bei den ersten Kompilationsversuchen erschien folgende Fehlermeldung …

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Docs Web 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ docs-web ---
[INFO] Deleting /usr/local/bin/sismics/docs-web/target
[INFO] 
[INFO] --- maven-antrun-plugin:1.8:run (default) @ docs-web ---
[INFO] Executing tasks

building:
     [exec] /usr/bin/env: ‘node’: No such file or directory
     [exec] Result: 127
[INFO] Executed tasks
[INFO] 
[INFO] --- maven-resources-plugin:2.7:resources (default-resources) @ docs-web ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO] Copying 1 resource
...

… und ich endete mit einem nur halbwegs funktionsfähigen .war, weil bestimmte nodejs-Komponenten fehlten:

building:
     [exec] /usr/bin/env: ‘node’: No such file or directory
     [exec] Result: 127

Der oben angelegte Symlink löst dieses Problem:

...
building:
     [exec] Running "clean:dist" (clean) task
     [exec] 
     [exec] Running "ngmin:dist" (ngmin) task
     [exec] ngminifying src/app/docs/app.js, src/app/docs/controller/Login.js, src/app/docs/controller/Main.js, src/app/docs/controller/Navigation.js, src/app/docs/controller/document/Document.js, src/app/docs/controller/document/DocumentDefault.js, src/app/docs/controller/document/DocumentEdit.js, src/app/docs/controller/document/DocumentModalPdf.js, src/app/docs/controller/document/DocumentModalShare.js, src/app/docs/controller/document/DocumentView.js, src/app/docs/controller/document/DocumentViewActivity.js, src/app/docs/controller/document/DocumentViewContent.js, src/app/docs/controller/document/DocumentViewPermissions.js, src/app/docs/controller/document/FileModalView.js, src/app/docs/controller/document/FileView.js, src/app/docs/controller/settings/Settings.js, src/app/docs/controller/settings/SettingsAccount.js, src/app/docs/controller/settings/SettingsDefault.js, src/app/docs/controller/settings/SettingsGroup.js, src/app/docs/controller/settings/SettingsGroupEdit.js, src/app/docs/controller/settings/SettingsLog.js, src/app/docs/controller/settings/SettingsSecurity.js, src/app/docs/controller/settings/SettingsSecurityModalDisableTotp.js, src/app/docs/controller/settings/SettingsSession.js, src/app/docs/controller/settings/SettingsUser.js, src/app/docs/controller/settings/SettingsUserEdit.js, src/app/docs/controller/settings/SettingsVocabulary.js, src/app/docs/controller/tag/Tag.js, src/app/docs/controller/usergroup/GroupProfile.js, src/app/docs/controller/usergroup/UserGroup.js, src/app/docs/controller/usergroup/UserProfile.js, src/app/docs/directive/Acl.js, src/app/docs/directive/AuditLog.js, src/app/docs/directive/File.js, src/app/docs/directive/ImgError.js, src/app/docs/directive/InlineEdit.js, src/app/docs/directive/SelectRelation.js, src/app/docs/directive/SelectTag.js, src/app/docs/filter/Filesize.js, src/app/docs/filter/Newline.js, src/app/docs/filter/Shorten.js, src/app/docs/service/Tag.js, src/app/docs/service/User.js, src/app/share/app.js, src/app/share/controller/FileModalView.js, src/app/share/controller/FileView.js, src/app/share/controller/Main.js, src/app/share/controller/Share.js, src/app/share/controller/ShareModalPdf.js, src/app/share/filter/Filesize.js, src/app/share/filter/Newline.js
     [exec] 
     [exec] Running "concat:docs" (concat) task
     [exec] File "dist/docs.js" created.
     [exec] 
     [exec] Running "concat:share" (concat) task
     [exec] File "dist/share.js" created.
     [exec] 
     [exec] Running "less:dist" (less) task
     [exec] File dist/less.css created.
     [exec] 
     [exec] Running "concat:css" (concat) task
     [exec] File "dist/style.css" created.
     [exec] 
     [exec] Running "cssmin:dist" (cssmin) task
     [exec] File 'dist/style/style.min.css' written.
     [exec] Uncompressed size: 165398 bytes.
     [exec] Compressed size: 31032 bytes gzipped (139383 bytes minified).
     [exec] 
     [exec] Running "uglify:docs" (uglify) task
     [exec] File dist/docs.min.js created.
     [exec] 
     [exec] Running "uglify:share" (uglify) task
     [exec] File dist/share.min.js created.
     [exec] 
     [exec] Running "copy:dist" (copy) task
     [exec] Created 23 directories, copied 53 files
     [exec] 
     [exec] Running "remove:dist" (remove) task
     [exec] 
     [exec] Running "cleanempty:src" (cleanempty) task
     [exec] Cleaning dist/locale...OK
     [exec] Cleaning dist/lib...OK
     [exec] 
     [exec] Running "htmlrefs:index" (htmlrefs) task
     [exec] 
     [exec] Running "htmlrefs:share" (htmlrefs) task
     [exec] 
     [exec] Running "replace:dist" (replace) task
     [exec] 
     [exec] Done, without errors.
...

Quelle: run npm command gives error „/usr/bin/env: node: No such file or directory“

.war kompilieren

Nun ist alles da, um das .war zu kompilieren:

# cd /usr/local/bin/sismics/docs-web
# mvn -Pprod -DskipTests clean install
...
[INFO] Installing /usr/local/bin/sismics/docs-web/target/docs-web-1.0-SNAPSHOT.war to /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.war
[INFO] Installing /usr/local/bin/sismics/docs-web/pom.xml to /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.935 s
[INFO] Finished at: 2016-03-27T10:37:55+00:00
[INFO] Final Memory: 28M/68M
[INFO] ------------------------------------------------------------------------

Jetty installieren und das .war bekanntmachen

Als nächstes installiert man Jetty:

# apt-get install jetty9

Sobald Jetty existiert, kopiert man das vorhin kompilierte .war in folgendes Verzeichnis:

# cp /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.war /usr/share/jetty9/webapps/dms.war

ACHTUNG: Es gibt auch ein Verzeichnis /usr/share/jetty/webapps/; Jetty ignoriert dieses aber (meiner Meinung nach). Das .war gehört nicht hierhin.

Datenverzeichnis anlegen

# mkdir /var/docs
# chmod 777 /var/docs

Jetty neu starten

# service jetty9 start

Sismics Docs aufrufen

Sobald Jetty läuft, öffnet man den Browser wieder:

10.1.2.3:8080/dms/

Man loggt sich ein, ändert das Admin-Passwort, erstellt weitere User, lädt ein Testdokument hoch, loggt sich wieder aus — und dann stoppt man Jetty testhalber wieder um sicherzugehen, dass die Daten und Konfiguration auch einen Stop des Applikationsservers überlegen:

# service jetty9 stop
# service jetty9 start

Nun sollte man sich mit dem soeben gesetzten Admin-Passwort einloggen können und das vorher hochgeladene Dokument sehen.

Fertig! Nun kann der Spass beginnen.

Die API-Dokumentation habe ich leider noch nicht gefunden …

Tags: , , , , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 30. April 2015

Unter Windows sequentiell nummerierte Verzeichnisse erstellen

Das geht ganz einfach, wenn man Git für Windows installiert hat und so auf die bash-Shell zurückgreifen kann:

$ for i in {50..75}; do mkdir $i; done

Tags: , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Montag, 2. März 2015

SAP-Datenexporte mit Unix-Tools filtern

Kürzlich stand ich vor der Aufgabe, einen 1.8 Millionen Zeilen umfassenden SAP-Export (SE16N, sowie Hintergründe) nach genau 16-stelligen Zahlenfolgen zu filtern. Anstelle Excel (kann sowieso nicht mit 1.8 Millionen Zeilen umgehen) oder das komplizierte ACL zu verwenden, entschied ich mich stattdessen, die Plaintext-Datei mit Unix-Tools zu filtern.

Inspiration dazu war der kürzlich auf Hacker News erschienene Artikel Command-line tools can be 235x faster than your Hadoop cluster.

Unter Windows klappt das problemlos, wenn man Github für Windows installiert hat – die Installation bringt nämlich eine Linux-Shell mitsamt den grundlegendsten Unix-Tools mit, so auch cat, grep und wc.

Um den SAP-Export mit „|“ als Feldabgrenzung auf den gesuchten Pattern zu filtern, habe ich folgenden Befehl verwendet:

$ cat export.txt | grep -E "\|[4-5]{1}[0-9]{15}" > export-filtered.txt

Dieser Befehl speichert alle Zeilen aus der Datei export.txt, welche 16-stellige Zahlen enthalten, die mit 4 oder 5 beginnen und am Anfang eines Feldes stehen (deshalb \|), in die Datei export-filtered.txt.

So entfiel der Import über eine graphische Oberfläche (mit der obligatorischen Titelleiste „Keine Rückmeldung“) und die Sache war innert 5 Minuten gegessen.

Tags: , , , , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 7. November 2012

Microsoft Domain Policies mit grep unter Windows filtern

Herkules-Aufgabe am Tag, an welchem Barack Obama zum neuen alten Präsident der USA gewählt wurde: Ich musste aus über 150 Domain Policies im HTML-Format diejenigen Dokumente herausfiltern, welche Passworteinstellungen enthielten. Und dies – wohlgemerkt – unter Windows. Wie macht man das?

Im Grund genommen ist das ganze keine grosse Hexerei:

  1. msysgit herunterladen
  2. msysgit installieren
  3. Git bash starten
  4. Ins Verzeichnis mit den Policies wechseln
  5. Folgenden Befehl ausführen:
    $ grep "Enforce password" *.html

Doch oha! grep liefert keine einzige Datei zurück, welche Kennwortrichtlinien enthält? Ein cat auf eine Beispieldatei zeigt, dass zwischen jedem Buchstaben ein Leerzeichen folgt. Indem man eine Beispieldatei mit Notepad++ öffnet, findet man heraus, dass die Exporte vom Domain Controller mit UCS-2 Little Endian enkodiert sind (der Zeichensatz steht in Notepad++ unten rechts in der Statusleiste).

Was nun? Ich habe mir kurzerhand ein bash-Script geschrieben, um die Dateien on-the-fly in ein für grep verständliches Format (UTF-8) zu konvertieren:

#!/bin/sh

if [ $# -lt 2 ]
then
	echo "Usage: $0 [extension of files to search] [string to search for in files]"
	exit 1
fi

for i in *.$1
do
	RES=`iconv -f UCS-2LE -t UTF-8 "$i" | grep "$2"`
	RET=$?

	if [ $RET -eq 0 ]
	then
		echo "$RET - $i"
		echo $RES
		echo ""
	fi
done

exit 0

Das Script tut folgendes: Zuerst liest es alle Dateien im aktuellen Verzeichnis aus, welche auf .html enden. In einer Schleife wird nun jede gefundene Datei mittels iconv von UCS-2LE nach UTF-8 konvertiert und an grep weitergepipet. grep sucht im Zeichensalat nach „Enforce password“. Die bash-Variable $? speichert das Resultat dieses Befehls; sprich 0 falls die Zeichenkette gefunden wurde, 1 (oder eine andere Zahl ungleich 0), wenn grep gestolpert ist oder einfach nichts gefunden hat. Ist $RET gleich 0, wird der Dateiname ausgegeben.

Schlussendlich fanden sich in den 150 Dateien gerade mal 6 Stück, welche Passworteinstellungen enthalten. Doch statt dem fehleranfälligen manuellen Geklicke habe ich quelloffene Tools, gepaart mit ein wenig Scripting-Wissen für mich arbeiten lassen.

Gut zu Wissen

Wer die Namen der Zeichensätze nicht auswendig weiss, dem wird unter folgendem Link geholfen:

libiconv

Tags: , , , , , , , , , , , , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Samstag, 27. August 2011

Mehrere private SSH-Schlüssel auf einem Rechner?

Kein Problem! Man benutze hierzu einfach Einträge in der Datei ~/.ssh/config à la:

Host github github.com
Hostname github.com
IdentityFile ~/.ssh/id_rsa_git

Quelle: Best way to use multiple ssh private keys on one client

Tags: , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Samstag, 27. August 2011

Kurzanleitung git

Vor einigen Wochen habe ich einen Account auf Github eröffnet und teile dort nützliche und weniger nützliche Programmierwürfe aus meiner Hand.

Da ich meine PHP-Entwicklungen mit Subversion verwalte und Git deshalb äusserst selten verwende, habe ich mir folgende Kurzanleitung von der Web-Site kopiert, damit ich ein Projekt im Nu eingecheckt habe.

Zuerst erstellt man sich unter Create a New Repository ein neues Repository. Anschliessend führt man lokal folgende Befehle aus:

mkdir arbeitsjournal
cd arbeitsjournal
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin git@github.com:emeidi/arbeitsjournal.git
git push -u origin master

Für alles weiterführende sei beispielsweise auf eines der vielen Git-Cheatsheets verwiesen.

Tags: ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen