Image bauen
docker build
.
Image ID herausfinden
docker images
Image taggen
docker tag <image id> < username/image_name>:latest
Evtl. in die Registry einloggen (mit Username nicht Emailadresse)
docker login
Image Pushen
docker push
Image bauen
docker build
.
Image ID herausfinden
docker images
Image taggen
docker tag <image id> < username/image_name>:latest
Evtl. in die Registry einloggen (mit Username nicht Emailadresse)
docker login
Image Pushen
docker push
1. Virtualenv anlegen
virtualenv -p python3 venv #if python2 is the default interpreter |
2. Libraries installieren (ipykernel nicht vergessen)
pip3 install -r requirements.txt #dependencies |
3. Kernel anlegen
python -m ipykernel install --user --name=venv |
4. Virtual Env aktivieren
source venv/bin/activate |
5. Im Playbook unter Kernel -> Change Kernel den Kernel venv wählen
6. Session beenden wenn Du fertig bist
deactivate |
Wenn die Uhr nicht korrekt auf dem Rechner eingestellt ist geschehen die lustigsten Dinge.
Deshalb synchronisiert sich Debian Linux per NTP gegen einen Zeitserver. Manchmal muß man jedoch an sowas vorbei arbeiten.
Um ein Script in der Vergangenheit oder Zukunft auszuführen muß NTP deaktiviert werden.
Unter Debian / Ubuntu funktioniert das so:
root@server:~# timedatectl set-ntp 0 root@server:~# timedatectl set-time 2017-06-20 root@server:~# date Tue Jun 20 00:00:01 CEST 2017 |
Im Anschluss auf keinen Fall vergessen NTP wieder zu aktivieren und die Uhr prüfen!
root@server:~# timedatectl set-ntp 1 root@server:~# date Wed Jun 21 12:30:45 CEST 2017 |
Kanboard ist eine nette Software um kleine Projekte oder im Ernstfall sich selbst per Kanban (angeblich spricht der Japaner das als „Kamban“ aus) zu managen. Ich nutze das für kleinere Projekte in- und abseits der Arbeit mit mehr oder weniger Erfolg. Ich habe eine Instanz auf Uberspace installiert weil das Hosting da schmerzfrei über die Bühne geht und ich keinen Server betreuen muß. Einzig der Webspace ist mit 10GB schmal bemessen. Installiert ist Kanboard über git clone – wenn ich mal Lust auf Features habe pull ich einfach den Masterbranch. Bei dieser Taktik wird leider auch jeder einzelne Commit auf die Platte gezogen.
Abhilfe schafft das abschneiden der History:
git clone --depth=1 --branch master https://github.com/fguillot/kanboard |
Bei composer das Flag –no-dev nicht vergessen
composer install --no-dev |
und die Installation ist um ~ 70% geschrumpft
40M kanboard.de |
141M kanboard.de.xxl |
Für bewegte Bilder auf der Glotze ist bei mir Kodi auf einem Raspberry Pi2 zuständig. Ich nutze dafür die Testbuilds von Milhouse weil man damit auch den Streaming Dienst von Amazon nutzen kann. Wie man das initial einrichtet erklärt Christoph von bei Linuxundich ganz gut. Da es sich um Testbuilds handelt macht es Sinn öfter mal ein Update einzuspielen. Wenn man das händisch macht ist es halt mit viel Arbeit verbunden und Arbeit sollten man vermeiden wo es nur geht. Deshalb habe ich ein kleines Script gebastelt welches mir diese Arbeit abnimmt. Die Geschichte ist natürlich bei weitem nicht perfekt. Ich habe aufgehört als es funktioniert hat.
Wichtig: mein Script lädt die Files für den Raspberry PI2 /3 wenn du einen Raspberry Pi 1 hast solltest Du dieses Script auf keinen Fall verwenden!
Um das ganze zum laufen zu bringen brauchst du PHP und Bash.
Die Scripte liegen in einem Repo auf Github wenn Du dir das genauer anschauen magst.
Falls nicht mußt du nur dieses Phar File und ein Bash Script downloaden und in ein bin folder legen – $USER/bin wäre ein schöner Ort dafür.
Nun muß noch das executable flag gesetzt werden:
chmod +x today-release.phar chmod +x update-kodi.sh |
Einfach das Script mit dem ssh String zum Raspberry aufrufen
update-kodi.sh kodi@192.168.0.89 |
Die Geschichte mit den Scripts ist schon ein wenig smelly. Eigentlich wollte ich mir das mit Ansible aufsetzen und das ADHS hat mich gezwungen diese Scripte zu erzeugen. Sinnvoll wäre es auch, wenn vor dem Einspielen des Updates die /etc/issue geprüft wird um zu schauen ob das Gerät schon auf der aktuellen Version läuft.
Ich parse die Url http://milhouse.libreelec.tv/builds/master/RPi2/ das ist ziemlich unelegant wie ich finde. Gibt es da vielleicht eine Art Http Standard um sowas direkt lesen zu können?
Langjährige Büroarbeit hat mir einen ordentlichen Bauch verschafft der ab und an die Kontrolle über die Tasten meines Touchpads übernimmt. Abhilfe schafft hier Sport und ein kleines Script um das Touchpad bei Bedarf zu deaktivieren. Das Script liest den Status des Touchpads aus und invertiert ihn.
#!/bin/bash DEVICE_NAME="SynPS/2 Synaptics TouchPad" #read state of the touchpad STATE=$(xinput list-props "$DEVICE_NAME" |grep "Device Enabled"|cut -f3) #flip the variable if [ $STATE = 1 ]; then echo disable $DEVICE_NAME STATE=0 else STATE=1 echo enable $DEVICE_NAME fi xinput set-prop "$DEVICE_NAME" "Device Enabled" $STATE |
Database Table Prefixes are easy to configure with the Doctrine Naming Strategies.
Just create and register a new Strategy in your global config:
config/autoload/global.php
<?php namespace Album\Doctrine\Strategy; use Doctrine\ORM\Mapping\DefaultNamingStrategy; class PrefixNamingStrategy extends DefaultNamingStrategy { /** * {@inheritdoc} */ public function classToTableName($className) { return '_' . substr($className, strrpos($className, '\\') + 1); } } |
<?php return array( /* ... */ 'doctrine' => array( 'configuration' => array( 'orm_default' => array( 'naming_strategy' => new \Album\Doctrine\Strategy\PrefixNamingStrategy() ), ), ), /* ... */ ); |
References:
Doctrine Manual Implementing a NamingStrategy
Vor ca. 9 Monaten hat mein Feedreader mir einen interessanten Artikel präsentiert. Er handelte von einem Elektronik-Modul namens ESP8266 der TCP/IP Kommunikation über WLAN mit Arduino Controllern ermöglicht. Low-Level Geschichten interessieren mich normalerweise nicht, weil es meist aufwändig und kostspielig war die Hardware ins Netz zu bringen- vor allem ohne Kabel. Dank der netten Ebay Händler aus Shenzhen bekommt man die Hardware für solche Unterfangen inzwischen unter 10€. Ich hatte das Teil sofort bestellt, aber habe es nie geschafft es in Betrieb zu nehmen weil immer was dazwischen kam und mir die Muße fehlte – bis vor ca. 1h. Warum meine ersten Versuche das Teil in Betrieb zu nehmen fehlschlugen kann ich leider nicht mehr sagen. Als ausgebildete Fachkraft bin ich zu 100% sicher die Schaltung 1:1 nachgebaut zu haben aber es wollte nicht klappen. Aufgrund solcher Gedächtnisslücken schreibe ich jetzt diesen Artikel:).
Auf der Website Instructables.com bin ich auf eine vergleichbare Anleitung gestoßen, die eine Verkabelung ohne Spannugnsteiler und Stützkondensator vorsieht und auf einmal hatte es funktioniert! In dem Tutorial dreht sich alles darum per Http Request Sensordaten von einem DS1820 Temperatursensor per HTTP auf eine recht interessante Seite namens Thingspeak zu übertragen. Ich habe den Code ein wenig angepasst, da ich weder die Hardware dafür besitze noch die Libraries einbinden wollte. Wenn Du das nachbauen möchtest benötigst Du einen Account auf der Seite und mußt den Präprozessor neben SSID und Passwort mit einen API-KEY für Thingspeak füttern.
#include #include #define SSID "SSID" #define PASS "PASSWORD" #define IP "184.106.153.149" // thingspeak.com String GET = "GET /update?key=[APIKEY]]&field1="; SoftwareSerial monitor(10, 11); // RX, TX void setup() { monitor.begin(9600); Serial.begin(9600); sendDebug("AT"); delay(5000); if(Serial.find("OK")){ monitor.println("RECEIVED: OK"); connectWiFi(); } } void loop(){ //float tempC = sensors.getTempCByIndex(0); char buffer[10]; String tempF = dtostrf(989, 4, 1, buffer); updateTemp(tempF); delay(60000); } void updateTemp(String tenmpF){ String cmd = "AT+CIPSTART=\"TCP\",\""; cmd += IP; cmd += "\",80"; sendDebug(cmd); delay(2000); if(Serial.find("Error")){ monitor.print("RECEIVED: Error"); return; } cmd = GET; cmd += tenmpF; cmd += "\r\n"; Serial.print("AT+CIPSEND="); Serial.println(cmd.length()); if(Serial.find(">")){ monitor.print(">"); monitor.print(cmd); Serial.print(cmd); }else{ sendDebug("AT+CIPCLOSE"); } if(Serial.find("OK")){ monitor.println("RECEIVED: OK"); }else{ monitor.println("RECEIVED: Error"); } } void sendDebug(String cmd){ monitor.print("SEND: "); monitor.println(cmd); Serial.println(cmd); } boolean connectWiFi(){ Serial.println("AT+CWMODE=1"); delay(2000); String cmd="AT+CWJAP=\""; cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; sendDebug(cmd); delay(5000); if(Serial.find("OK")){ monitor.println("RECEIVED: OK"); return true; }else{ monitor.println("RECEIVED: Error"); return false; } } |
Die Verdrahtung gestaltet sich sehr einfach und funktioniert mit meinem Arduino UNO- und dem Arduino NANO 328-Klon:
ESP8266 | Arduino |
---|---|
TXD | RXD |
CH_PD | VCC 3V3 |
VXX | VCC 3V3 |
GND | GND |
RXD | TXD |
Die Pins auf dem WLAN Chip sind so belegt:
Hier 2 Bilder die zeigen wie die PINS auf den Arduinos herausgeführt sind:
Tükisch waren 2 Dinge an der Geschichte:
In den kommenden Tagen werde ich wohl ein kleines Programm schreiben, daß auf Port 80 lauscht und entsprechenden POST Requests analoge und digitale Ports schaltet und Stati ausgibt. Auch eine Anbindung an mein Openhab wäre sehr nett…
Ich schreibe sehr gerne Bash Scripte, aber noch lieber Scripte in PHP. Solange man alles in ein File bekommt ist das auch kein Problem. Bei größeren Geschichten oder bei der Verwendung von Libs streut das Script leider auf mehrere Dateien. Entsprechend sind Installation und Updates dann auch aufwendiger. Irgendwer hat sich für diese Problematik Phar (PHP Archive) ausgedacht. Dabei werden alle Abhängigkeiten in ein komprimiertes Archiv gepackt – vom Prinzip her wie ein Jar in Java. Das manuelle Erzeugen von diesen Dateien ist leider recht unangenehm und verbraucht nach zuviel Zeit. Viel schneller geht’s mit dem PHP PHAR Compiler von Christian Neff. Bevor man loslegen kann muß die php.ini angepasst werden:
phar.readonly = 0
Anschließend den Compiler via Composer installieren und ein Script zum Bauen anlegen:
<?php /** * User: ms * Date: 29.08.15 * Time: 20:22 * @see https://github.com/secondtruth/php-phar-compiler */ require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'vendor/autoload.php'; use Secondtruth\Compiler\Compiler; $compiler = new Compiler('./'); $compiler->addIndexFile('cli.php'); $compiler->addFile('vendor/autoload.php'); $compiler->addDirectory('vendor/composer', '!*.php'); $compiler->addDirectory('vendor/electrolinux', '!*.php'); $compiler->addDirectory('vendor/zendframework', '!*.php'); $compiler->addDirectory('src', '!*.php'); $compiler->compile("build/mvv-cli.phar"); |
Fertig.
Momentan konfiguriere ich mir einen Jenkins CI Server für private PHP Sachen. Da ich das nicht alle Tage mache schreibe ich mir hakelige Sachen oder Dinge die ich recherchieren mußte hier für das nächste mal nieder. Ich werde den Server primär zum Ausführen von Unit-Tests, dem Erzeugen von Dokumentation und Softwaremetriken nutzen. Eventuell hänge ich noch ein Deployment dran.
Eine schöne Anleitung für die PHP Projekte gibt es hier. Wenn man den Server per Kommandozeile steuern möchte – um z.B. Plugins zu installieren – muß man sich per SSH Key authentifizieren.
Hier die Konfiguration auf der Kommandozeile + Webinterface im Schnelldurchgang:
Von der Seite http://yourserver.com/cli runterladen – der Eintrag im Jenkins Wiki zu dem Thema ist auch sehr nützlich
ms@jenkins:~$ ssh-keygen -t rsa -b 4096 Generating public/private rsa key pair. Enter file in which to save the key (/home/ms/.ssh/id_rsa): id_rsa_jenkins_cli Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in id_rsa_jenkins_cli. Your public key has been saved in id_rsa_jenkins_cli.pub. The key fingerprint is: xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx ms@jenkins The key's randomart image is: +--[ RSA 4096]----+ | cxxxxxxxxxxx | | xxxxxxxxxxxx | | xxxxxxxxxxxx | | xxxxxxxxxx | | xxxxxxxx | | x | | | | | | | +-----------------+ ms@jenkins:~$ mv id_rsa_jenkins_cli* .ssh/ |
Die Url lautet https://yourserver.com/me/configure
ms@jenkins:~$ cat .ssh/id_rsa_jenkins_cli.pub |
ms@jenkins:~$ java -jar jenkins-cli.jar -i .ssh/id_rsa_jenkins_cli -s http://localhost/jenkins install-plugin checkstyle cloverphp crap4j dry htmlpublisher jdepend plot pmd violations warnings xunit Installing checkstyle from update center Installing cloverphp from update center Installing crap4j from update center Installing dry from update center Installing htmlpublisher from update center Installing jdepend from update center Installing plot from update center Installing pmd from update center Installing violations from update center Installing warnings from update center Installing xunit from update center |