Pages Menu
Rss
Categories Menu

Die neuesten Artikel

Rails Logfiles rollieren

Gepostet by on Jun 26, 2013 in Coding, Ruby | Keine Kommentare

rails-full.pngSobald man mit einer Rails Anwendung fertig ist und sie auf dem entsprechenden Server installiert ist, wird oft eine Kleinigkeit übersehen. Das Logfile production.log, in welches unaufhörlich geschrieben wird…

 

Allgemein gibt es ja viele Wege um Logfiles rollieren zu lassen, z.B. logrotate unter Linux. Dafür ist allerdings wieder eine eigene Konfiguration nötig. Allerdings kann sich auch Rails selber um die Rotierung der Logfiles kümmern. Die Einstellung kann direkt in config/environments/production.rb vorgenommen werden:

config.logger = Logger.new(Rails.root.join('log',"#{Rails.env}.log"),3,5.megabytes)

Das Logfile wird dann automatisch nach 5 MB rolliert und es werden insgesamt 3 Logfiles aufgehoben.

Rails Update von 3.0 auf 3.1

Gepostet by on Mrz 18, 2013 in Coding, Ruby | Keine Kommentare

rails-full.pngWäre es doch schön, wenn man fertige Applikationen einfach weiter laufen lassen könnte, ohne dass man sich weiter darum kümmern muss…aber leider funktioniert das nicht. Immer wieder werden neue Sicherheitslücken in dem verwendete Framework oder Gems entdeckt, so dass man eigentlich ständig am Ball bleiben muss. Problematisch wird es nämlich, wenn man längere Zeit keine Updates gemacht hat, dann steht man irgendwann vor einem richtig großem Versionssprung und hat u.U. einen nicht überschaubaren Aufwand…

Langsam wurde es auch Zeit, dass ich eine Rails 3.0 Anwendung auf mind. 3.1 aktualisiere, da es absehbar wird, dass für 3.0.x keine Sicherheitspatches mehr bereit gestellt werden.

Zuerst muss für das Update das Gemfile angepasst werden, damit auch die richtige Rails Version und deren neue Abhängigkeiten berücksichtig wird:

gem 'rails', '= 3.1.11'
gem 'mysql2'
 
group :assets do
  gem 'sass-rails', "~> 3.1.5"
  gem 'coffee-rails', "~> 3.1.1"
  gem 'uglifier', ">= 1.0.3"
end
 
gem 'jquery-rails'

Falls das Gem mysql verwendet wurde, ist es wichtig dass jetzt das Gem mysql2 verwendet werden muss. Ob auch das jquery-rails verwendet werden soll ist eine Frage der aktuellen Applikation. Per default wird es von Rails 3.1 eingetragen, kann aber u.U. zu Problemen führen, wenn eine benutzerdefinierte jQuery Version inkl. jQuery UI schon verwendet wird. In meinem Fall habe ich es nicht mit eingetragen und jQuery direkt als Asset hinterlegt.

Sobald das Gemfile angepasst ist, müssen wir die neuen Gems installieren:

$ bundle update

Anschließend das Rails Projekt aktualisieren:

$ rake rails:update

Nach dem Update müssen vermutlich noch einige Konflikte gelöst werden, welche durch das Update zustande kamen.

Ein Hauptfeature der Version 3.1 ist die Assets Pipeline, welche in der Datei config/application.rb aktiviert werden kann:

# Enable the asset pipeline  
config.assets.enabled = true  
 
# Version of your assets, change this if you want to expire all your assets  
config.assets.version = '1.0'

Als nächstes müssen die zugehörigen Einstellungen für jedes Environment vorgenommen werden. In config/environments/development.rb sollte die Komprimierung und das Debugging der Assets aktiviert werden:

# Do not compress assets  
config.assets.compress = false  
 
# Expands the lines which load the assets  
config.assets.debug = true

Und in config/environments/production.rb konfigurieren wir, dass die Assets komprimiert, aber nicht kompiliert werden.

# Compress JavaScript and CSS  
config.assets.compress = true  
 
# Don't fallback to assets pipeline  
config.assets.compile = false  
 
# Generate digests for assets URLs  
config.assets.digest = true

Die Option config.assets.compile sollte bei produktiv Systemen auf false gesetzt werden, da sonst Rails nicht vorhanden Assets live kompilieren will. Das bedeutet, dass alle Assets vor dem Deployment auf dem live System mit Rake kompiliert werden müssen:

$ rake assets:precompile

Wenn die Anwendung z.B. mit Capistrano installiert wird, dann übernimmt Capistrano automatisch den Task.

Da jetzt die Anwendung konfiguriert ist, können alle Assets an den neuen Platz verschoben werden:

$ mkdir app/assets
$ mv public/images/ app/assets/
$ mv public/javascripts/ app/assets/
$ mv public/stylesheets/ app/assets/

Grafiken, JavaScripts und Stylesheets liegen jetzt nicht mehr unterhalb von public, sondern unter app/assets.

Rails kennt aber noch nicht alle Assets bzw. weiss noch nicht welche Dateien auch kompiliert werden sollen. Alle JavaScript Dateien und Stylesheets müssen deshalb in den entsprechenden Manifest Dateien, app/assets/javascript/application.js und app/assets/stylesheets/application.css, aufeglistet werden.

Das Manifest application.js kann z.B. wie folgt aussehen:

// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require_tree .

Durch die Angabe require_tree werden automatisch alle Dateien innerhalb des gleichen Ordners mit eingebunden. Für die Stylesheets sieht das Manifest application.css ähnlich aus:

/*
 * This is a manifest file that'll automatically include all the stylesheets available in this directory
 * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
 * the top of the compiled file, but it's generally better to create a new file per style scope.
 *= require_self
 *= require_tree . 
*/

Auch hier kann mit require_tree das ganze Verzeichnis eingebunden werden. Durch die Manifest Dateien müssen im Template auch nicht mehr mehrere Dateien eingebunden werden:

<%= stylesheet_link_tag    "application" %>
<%= javascript_include_tag "application" %>

Im Großen und Ganzen ist das Update eigentlich recht schmerzfrei. Der wirklich große Unterschied besteht hauptsächlich in der Assets Pipeline, mit welcher man sich vermutlich erstmal anfreunden muss.

Die Surfer am Münchner Eisbach

Gepostet by on Mrz 3, 2013 in Reise | Keine Kommentare

Eisbach 1Der Eisbach ist im Sommer in München ein kleiner und mittlerweile nicht mehr ganz so geheimer, Touristen Hotspot. Der Eisbach ist Teil des Englischen Gartens und fließt unterirdisch durch die Münchner Altstadt und den Stadtteil Lehel. Am südlichen Rand des Englischen Gartens in unmittelbarer Nähe des Hauses der Kunst kommt er wieder an die Oberfläche. Das besondere an diesem Bach ist eine stehende Welle, welche von Surfern benutzt wird und international auch schon bekannt wurde.

Eisbach 2Die Welle ist bei Wellenreitern sowohl geliebt als auch gefürchtet, weil direkt hinter der Welle mehrere Reihen von Steinquadern unter Wasser sind. Aus diesem Grund sind hier in der Regel nur erfahrene Wellenreiter zu bestaunen, da die Verletzungsgefahr für Anfänger sehr hoch ist.

Eisbach 3Eisbach 4

 Die Fotos habe ich im Sommer 2011 aufgenommen.

Mercurial merges mit nicht eingecheckten Änderungen

Gepostet by on Mrz 1, 2013 in Coding | Keine Kommentare

droplets-75Machmal nervt Mercurial wirklich und man wünscht sich einen staging Bereich für nicht eingecheckte Änderungen wie bei Git. Es kann nämlich durchaus passieren, dass man ein paar Changesets aus einem entfernten Repository holen und einen merge bzw. rebase machen muss, obwohl die eigenen Änderungen noch nicht eingecheckt sind.

Mercurial erlaubt aber genau dies nicht, dann kommt es nämlich zu folgender Meldung:

% hg merge
abort: outstanding uncommitted changes

Es gibt aber einen relativ einfachen Weg, um das Problem zu umgehen. Man exportiert temporär die eigenen Änderungen in einen Patch und macht diese dann im Repository rückgängig:

% hg diff > /tmp/local_changes.diff
% hg revert -a

Jetzt kann der eigentliche merge bzw. rebase ausgeführt werden, da das lokale Verzeichnis wieder sauber ist. Danach können die eigenen Sachen wieder importiert werden:

% hg import --no-commit /tmp/local_changes.diff

Es ist jetzt nicht der schönste Weg, aber es funktioniert wenigstens…

FreeBSD crash bei UFS dump

Gepostet by on Jan 25, 2013 in Unix | 1 Kommentar

Vor einiger Zeit bin ich über einen ziemlich fiesen Bug in FreeBSD gestolpert, der das komplette System zum abstürzen bringt und das während dem Backup…

Ich hatte einen neue Server mit FreeBSD 9 installiert, als Dateisystem kam UFS mit den Standard Einstellungen zum Einsatz. Nachdem ich den Server im Rechenzentrum verschraubt hatte, habe ich ganz normal das Backup mit Amanda aktiviert….man will ja auch seine Kiste gesichert haben.

Als ich am nächsten morgen mich auf dem Server anmelden wollte kam die böse Überraschung. Der ganze Server war weg, nicht mal ein ging mehr. Mir blieb nichts anderes übrig als wieder ins Rechenzentrum zu fahren. Nachdem ich lokal eine Konsole angeschlossen hatte, merkte ich, dass selbst damit ein Login auf nicht mehr möglich war. Nach einem Reset konnte ich dann schließlich im Logfile noch die letzten Meldungen sehen…

Dec 17 01:18:57 havanna kernel: fsync: giving up on dirty
Dec 17 01:18:57 havanna kernel: 0xfffffe0003853960: tag devfs, type VCHR
Dec 17 01:18:57 havanna kernel: usecount 1, writecount 0, refcount 956 mountedhere 0xfffffe0003da7800
Dec 17 01:18:57 havanna kernel: flags ()
Dec 17 01:18:57 havanna kernel: v_object 0xfffffe0003505ca8 ref 0 pages 9467
Dec 17 01:18:57 havanna kernel: lock type devfs: EXCL by thread 0xfffffe003aac3460 (pid 15721)
Dec 17 01:18:57 havanna kernel: dev da0p2
Dec 17 01:19:09 havanna sendbackup[15713]: error [dump (15717) /sbin/dump returned 1]

Es hatte also was mit dem Backup zu tun. Nach einiger Recherche bin ich dann über folgenden Beitrag auf der FreeBSD Mailing Liste gestolpert http://lists.freebsd.org/pipermail/freebsd-stable/2012-January/065756.html

Wenn bei UFS Softupdates und Journaling gleichzeitig aktiviert sind und dump(8) ausgeführt wird, dann stirbt das ganze System. Sofern man weiterhin dump(8) verwenden will, bleibt einem nichts anderes übrig, als das Journaling zu deaktivieren. Dazu muss man allerdings das entsprechende Dateisystem ausgehängt sein. Wenn es sich um / handelt, muss man leider mit einer Live-CD booten. Zum deaktivieren muss dann tunefs(8) verwenden:

> umount
> tunefs -j disable
> mount
> cd
> rm .sujournal

Danach funktionierte das Backup mit dump(8) wieder einwandfrei. Ich glaube der Bug ist sogar noch in FreebSD 9.1 drin, ich habe jedenfalls noch nichts gefunden, dass er behoben ist.

Mit Apache Bilderklau unterbinden

Gepostet by on Jul 3, 2012 in Unix | 1 Kommentar

Schon mal erlebt, dass die eigenen Bilder auf einer fremden Seite verlinkt werden und man dadurch erhöhten Traffic hat? Zum Glück gibt es mit Apache einige einfache Möglichkeiten dies zu unterbinden.

In den Apache Logfiles kann man recht einfach erkennen, ob Grafiken in einer anderen Seite eingebunden wurden. Sobald einzelne Zugriffe nur auf Grafiken gemacht werden und der Referer nicht die eigene Domain ist, liegt die Vermutung nahe, dass auf der Seite des Referers die eigene Grafik eingebunden wurde.

Eine Möglichkeit besteht darin, unerwünschte Referer komplett mit mod_rewrite zu blocken. Dies kann z.B. in einer .htaccess Datei konfiguriert werden:

RewriteEngine on
RewriteCond %{HTTP_REFERER} ^http://www.badreferer.tld$ [OR]
RewriteCond %{HTTP_REFERER} ^http://anotherbadreferer.tld$
RewriteRule .* - [F,L]

Mit der obigen Konfiguration werden die Referer www.badreferer.tld und anotherbadreferer.tld komplett geblockt und bekommen den Status Code 403 zurück.

Will man aber z.B. verhindern, dass alle Grafiken von externen Seite aus geladen werden können, dann könnte man dies z.B. wie folgt machen

SetEnvIfNoCase Referer "treibsand.com" ok=1
<FilesMatch ".(gif|jpg|png)">
  Order Allow,Deny
  Allow from env=ok
</FilesMatch>

Sobald der Referer die eigene Domain ist, hier treibsand.com, wird der Variable ok auf 1 gesetzt. Anschließend wird die Auslieferung aller Dateien mit den Endungen .gif, .jpg und .png nur erlaubt, wenn die Variable ok gesetzt ist. Sollte die Variable ok nicht gesetzt sein, bekommt der Client den Status Code 403 zurück.