Domů > Linuxové zápisky pro správce > watcher.py: Vykonání určité akce, když se změní struktura dat

watcher.py: Vykonání určité akce, když se změní struktura dat

Lepší nadpis příspěvku mě nenapadl, ale myslím, že když budete číst dál, tak určitě pochopíte, k čemu je to dobré.

Situace

Na serveru mám sdílený adresář /PUBLIC exportovaný přes NFS. Jak z názvu plyne, jedná se o veřejné úložiště, ale ve smyslu, že může číst a zapisovat jen skupina „public“ a její členové. Výchozí skupina uživatelů je ale „Domain users“ a proto bylo zapotřebí, aby se při nakopírování, přesunutí, vytvoření souboru/adresáře do /PUBLIC změnila jeho skupina na „public“.

Změna skupiny

Při vytváření souboru/adresáře jsem toho docílil tak, že jsem nastavil dědičnost skupiny

chmod -R g+s /PUBLIC

problém ale samozřejmě nastal ve chvíli, když do /PUBLIC byl soubor/adresář přesunut nebo zkopírován. Zůstala mu totiž jeho původní skupina a to bylo v tomto případě nežádoucí.

Změna práv

Další problém byl v právech. Uživatelé vytvářeli soubory s umask 022 (soubory 644 a adresáře 755), ale já potřeboval aby to bylo 660 a 770 (samozřejmě pouze ve sdíleném adresáři). Tzn. aby mohli zapisovat a číst všichni uživatelé ve skupině. Toho jsem docílil pomocí ACL.

setfacl -Rdm u::rwX,g::rwX,o::- /PUBLIC

Přichází ale opět na řadu kopírování a přesouvání. Práva, stejně jako skupina, zůstala nezměněná.

Historie nastavení

Proto jsem se rozhodl dát do cronu skript, který mi v 10ti minutových intervalech bude práva měnit. Mělo to ale své nevýhody. Dalo by se vydržet, že uživatel musel čekat pár minut na změnu práv. Ale horší bylo, že když kopíroval do /PUBLIC větší soubor déle jak těch 10 minut, proběhla změna práv a kopírování se přerušilo.

Proto nastoupil incron. Ten ale bohužel neuměl pracovat rekurzivně. Tzn. že uměl hlídat opravdu jen složku /PUBLIC, ale když uživatel něco nakopíroval do /PUBLIC/Dokumenty, incron o tom nevěděl.

Konečné řešení

Hledal jsem tedy dál a našel jsem watcher.py, který toto umí.

Hlavní doména tohoto programu je, že jeho démon hlídá vámi definovaný adresář (v našem případe /PUBLIC) a hlídá změny, které se uvnitř něho odehrávají (a to i v jeho podadresářích). Na základě toho umí vyvolávat akce, spouštět skripty atd.

Nyní mi tedy watcher.py hlídá /PUBLIC a když se v něm objeví nějaký soubor/adresář, tak spustí skriptík, který mu změní práva.

Instalace

Stáhneme si watcher.py a jeho konfigurační soubor. Já to udělal pro přehlednost tak, že jsem watcher.py přejmenoval na watcher a nakopíroval (nebo můžete vytvořit symlink) do /etc/init.d. Nyní ho spustíme klasickým příkazem

/etc/init.d/warcher start

Nezapomeňte v tomto souboru ještě uměnit cestu ke konfiguračnímu souboru, ten jsem uložil jako /etc/watcher/watcher.conf. Jeho obsah mám zhruba takovýto:

Aby se nám démon watcher spouštěl po startu serveru, přidáme jeho symlink do patřičného runlevellu.

Konfigurace

Konfigurační soubor (ten co už máme v /etc/watcher/watcher.conf) je pěkně komentovaný


; ----------------------
; General Settings
; ----------------------
[DEFAULT]

; where to store output
logfile=/var/log/watcher.log
;logfile=/dev/null

; where to save the PID file
pidfile=/tmp/watcher.pid
; ----------------------
; Job Setups
; ----------------------

[job1]
; directory or file to watch. Probably should be abs path.
watch=/shares/PUBLIC

; list of events to watch for.
; supported events:
; 'access' - File was accessed (read) (*)
; 'attribute_change' - Metadata changed (permissions, timestamps, extended attributes, etc.) (*)
; 'write_close' - File opened for writing was closed (*)
; 'nowrite_close' - File not opened for writing was closed (*)
; 'create' - File/directory created in watched directory (*)
; 'delete' - File/directory deleted from watched directory (*)
; 'self_delete' - Watched file/directory was itself deleted
; 'modify' - File was modified (*)
; 'self_move' - Watched file/directory was itself moved
; 'move_from' - File moved out of watched directory (*)
; 'move_to' - File moved into watched directory (*)
; 'open' - File was opened (*)
; 'all' - Any of the above events are fired
; 'move' - A combination of 'move_from' and 'move_to'
; 'close' - A combination of 'write_close' and 'nowrite_close'
;
; When monitoring a directory, the events marked with an asterisk (*) above
; can occur for files in the directory, in which case the name field in the
; returned event data identifies the name of the file within the directory.
events=create
;events=all

; if true, watcher will monitor directories recursively for changes
recursive=true

; the command to run. Can be any command. It's run as whatever user started watcher.
; The following wildards may be used inside command specification:
; $$ dollar sign
; $watched watched filesystem path (see above)
; $filename event-related file name
; $tflags event flags (textually)
; $nflags event flags (numerically)
; $dest_file this will manage recursion better if included as the dest (especially when copying or similar)
; if $dest_file was left out of the command below, Watcher won't properly
; handle newly created directories when watching recursively. It's fine
; to leave out when recursive is false or you won't be creating new
; directories.
;command=cp -r $filename /home/user/Documents/$dest_file
command=/usr/local/scripts/public-perm $filename

[job2]
watch=/AUDIO
events=create,move_to
recursive=true
command=/usr/local/scripts/audio-perm $filename

Vytvořil jsem dva joby, kde jsem zadal, který adresář se má hlídat a jakou akci za jakých podmínek vykonat. Pokud tedy něco vytvoříme nebo přesuneme do kontrolovaného adresáře, spustí se skript. Např. /usr/local/scripts/audio-perm, v mém případě s následujícím obsahem:

#!/bin/bash

sleep 3 &&

/bin/chmod -R ugo= "$1"
/bin/chmod -R u=rwX,g=rX,o= "$1"
/bin/chown -R :audio "$1" 

Měním tedy práva a skupinu ($1 je aktuálně přenášený soubor/adresář)  s 3 vteřinovým zpožděním. To proto, aby se akce provedla až po dokončení přenosu souboru. Pokud budete tedy potřebovat větší soubory, je lepší tento interval prodloužit (nenašel jsem totiž jinou možnost, jak akci automaticky provést až po dokončení zápisu).

Další možnosti

Ve sdílení mám např. adresář, kam uživatelé přidávají dokumenty. Proto jsem watcher nastavil tak, aby mi při vytvoření nového souboru přišel o této situaci mail s informací, že na serveru je nový soubor (vč. jeho názvu). Stačilo přidat do skriptu něco takového:


# odesle informaci o novem souboru do mailu

/usr/sbin/sendmail odkud@example.net <<END
From: Film Watcher <no-reply@example.net>
Subject: Novy soubor na serveru
TO: Film Watcher <komu@example.net>

Na serveru se objevil novy soubor: $1

END

Závěr

Watcher plní svojí funkci velice dobře. Je zde spousta možností, jaké akce provádět, fantazii se meze nekladou.

Zdroje informací

http://www.splitbrain.org/blog/2011-01/07-watcher_a_recursive_incron_alternative
http://www.abclinuxu.cz/poradna/linux/show/352581

  1. Pavel Jindra
    05.01.2014 na 12:58 | #1

    Super, dikys za navod a tip. Hodne mi to pomohlou a usetrilo cas:)

  1. Žádné zpětné odkazy