czwartek, 27 maja 2010

Konfigurowanie Apacha

Rozpoczynam od założenia w serwisie dyndns.org konta. Potem przechodzę do My ServicesHost services, wybieram nazwę hosta (w moim przypadku pinkaccordions) i domeny (homelinux.org). Typ usługi: Host with IP address. Resztę pól można zostawić niewypełnione. Darmowe konto pozwala na przydzielenie 5 adresów...

Teraz w menu Tomato klikam w Basic→DDNS. Jako service wybieram DynDNS -- static, Username/Password to dane z rejestracji w serwisie DynDNS, hostname to z kolei wybrana przez nas nazwa hosta, tj. w moim przypadku pinkaccordions.homelinux.org. Więcej niczego nie trzeba wpisywać wystarczą dane domyślne. Można ustawić w ten sposób dwa adresy... Por też notatki tutaj.

Pozostaje wreszcie uruchamienie usługi port forwarding na routerze z działającym Tomato. Jest to bardzo proste i sprowadza się do wypełnienia pól Proto, Ext Ports, Int Address oraz opcjonalnie Description (por. ekran obok).

Instalacja serwera apache oraz php w systemie Debian Lenny.


apt-get install apache2 apache2-mpm-prefork apache2-utils apache2.2-common
apt-get install php5 libapache2-mod-php5 php5-common php5-curl
apt-get install php5-dev php5-gd php5-imagick php5-mcrypt php5-memcache php5-mhash \
php5-mysql php5-pspell php5-snmp php5-sqlite php5-xmlrpc php5-xsl

W pliku /etc/apache2/ports.conf umieszczam komentarz przed dyrektywą NameVirtualHost:


#NameVirtualHost *:80

Zaś powyższą dyrektywę umieszczam w /etc/apache2/httpd.conf.

Konfiguracja wirtualnego hosta; plik /etc/apache2/sites-available/pinkaccordions powstaje przez skopiowanie pliku domyślnego:


cd /etc/apache2/sites-available/ ; cp default pinkaccordions

Następnie plik modyfikuję dopisując ServerName i ServerAlias



<VirtualHost *:80>
ServerAdmin webmaster@localhost

ServerName pinkaccordions.homelinux.org
ServerAlias pinkaccordions.homelinux.org

DocumentRoot /var/www_pinkaccordions/
<!-- dalej w zasadzie niezmienione -->
</VirtualHost>

Teraz:


cd /etc/apache2/sites-enabled && ln -s ../sites-available/pinkaccordions pinkaccordions

To samo dla drugiego i ewentualnie kolejnych hostów. Innych plików za wyjątkiem opisanych wyżej httpd.conf, ports.conf oraz plików z katalogu ./sites-available/ i linków z katalogu ./sites-enabled/ nie ruszam. Teraz


/etc/init.d/apache2 restart
# albo apache2ctl graceful

No i powinno działać...

Dopisane 15 września 2010: Aby logrotate nie usuwał najstarszego przechowywanego pliku modyfikuję /etc/logrotate.d/apache2 i dodając stosowane prerotate...endscript:


sharedscripts
prerotate
if [ -f "/path2logs/access.log.52.gz" ] ; then
cp /path2logs/access.log.52.gz /path2archive/access.`date +%Y%m%d`.log.gz ; fi
if [ -f "/path2logs/access.fabians.log.52.gz" ] ; then
cp /path2logs/access.log.52.gz /path2logs/access.`date +%Y%m%d`.log.gz ; fi
endscript

Teraz (mam nadzieję), plik access.log.52.gz przed skasowaniem zostanie skopiowany w inne miejsce i ocaleje. Pewnie można by prościej, przykładowo brutalnie wpisując po prostu rotate 156.

Rekursywne przeglądanie wszystkich plików

Na potrzeby dostosowana adresów URL do innej konfiguracji innego serwera wykorzystałem następujący skrypt:


#!/usr/bin/perl -w
use strict;
undef $/; ## na potrzeby czytania każdego pliku (process_file)

sub recurse($) {
my($path) = @_;

## append a trailing / if it's not there
$path .= '/' if($path !~ /\/$/);
## print the directory being searched
print STDERR $path,"\n";

## loop through the files contained in the directory
for my $eachFile (glob($path.'*')) {

## if the file is a directory
if( -d $eachFile) {
## pass the directory to the routine ( recursion )
recurse($eachFile);
} else {

## przetwarzaj plik
process_file ($eachFile);
}
}
}

sub process_file {
my $file = shift;
## Tylko pliki .html i .php
if ($file =~ /\.html|\.php$/) {
my $tmp_file = "$file.temp";
rename($file, $tmp_file);

open (F, $tmp_file); open (FO, ">$file");
my $ff = <F>;

## zamień bezwględne URLe na lepsze
$ff =~ s/href=(["'])http:\/\/gnu.univ.gda.pl\/~tomasz/href=$1/g; ## zamień
$ff =~ s/src=(["'])http:\/\/gnu.univ.gda.pl\/~tomasz/src=$1/g; ## zamień

print STDERR "-> $file\n";
print FO $ff;
close(F);
close (FO);
}
}

## initial call ... $ARGV[0] is the first command line argument
recurse($ARGV[0]);

Wymieniając procedurę process_file można oczywiście ww. skrypt zaadaptować do innych zadań, np. poprawienia zepsutej daty modyfikacji plików:-)

wtorek, 25 maja 2010

Kopia zapasowa karty SDHC, rsync i problemy

Uruchomiłem na Szewie #2 serwer WWW, dostępny pod adresem pinkaccordions.homelinux.org (darmowa domena z serwisu dyndys.com -- w moim przypadku konieczność, bo mam tzw. zmienne IP). Jak już jest serwer, to trzeba robić -- w sposób systematyczny, a nie ad hoc -- kopie zapasowe na wypadek gdyby, np. karta padła (co podobno nie jest takie rzadkie...). Po konsultacji z tym co w tym temacie proponują inni postanowiłem robić to za pomocą rsynca, uruchamianego z zewnętrznego komputera.

W tym celu trzeba zainstalować rsync na obu komputerach źródłowym i tym, na którym będzie tworzona kopia:


apt-get install rsync

Teraz należy skonfigurować rsync po stronie źródła (czyli tego komputera, z którego mają być kopiowane dane) modyfikując /etc/rsyncd.conf. Zawartość pliku /etc/rsyncd.conf w moim przypadku wygląda następująco:


## http://encodable.com/tech/blog/2005/10/13/Secure_Remote_Backups_via_rsync
uid = 0
gid = 0
hosts allow = *****
transfer logging = no
read only = yes

[wholefs]
path = /
comment whole root fs

[pinkaccordions]
path = /var/www_pinkaccordions/
comment pinkaccordions www

Można sprawdzić czy działa (neptune jest zadeklarowany w /etc/hosts):


rsync neptune::wholefs/

Tworzenie kopii realizuje skrypt rsync_neptune.sh uruchamiany po stronie przeznaczenia:


#!/bin/bash
SOURCE=neptune::wholefs/
EXCLUDE=/root/.rsync/backup_exclude.lst
DESTDIR=/backup/neptune/rootfs

echo "=== Syncing ${SOURCE} at `date` ==="
rsync -av --exclude-from=${EXCLUDE} --delete ${SOURCE} ${DESTDIR}

Plik $EXCLUDE zawiera te katalogi, które nie powinny -- z oczywistych względów -- być kopiowane (zawartości katalogów /proc, /sys oraz /tmp):


## Exclude
- /proc/*
- /sys/*
- /tmp/*

Skrypt rsync_neptune.sh jest zaś uruchamiany poprzez crona:


0 4 * * 7 /root/bin/rsync_neptune.sh >> /root/logs/RSync/RSync.log 2>&1

Idea jest taka: kopia całego rootfs z karty SDHC ma być wykonywana na dysk USB raz w tygodniu (z innego komputera, konkretnie Szewy #1). W razie potrzeby (awarii karty SDHC) kopia ta może być szybko przeniesiona na inną kartę SDHC... Można też kopiować bezpośrednio na kartę SDHC wsadzoną na zicher w czytnik kart, ale nie widzę sensu podłączania czytnika wyłącznie i tylko po to, żeby w razie awarii, mieć kopię karty od razu a nie po 3 minutach.

Zatem:


#!/bin/bash
EXCLUDE=/root/.rsync/backup_exclude.lst
SOURCE=/public/sheeva/backup/neptune/rootfs/
DESTDIR=/media/sd_backup

# http://www.cyberciti.biz/tips/shell-root-user-check-script.html
# Make sure only root can run our script
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2 ; exit 1
fi

## sprawdz czy karta jest w czytniku i jest zamontowana
if [ -d "$DESTDIR" ] ; then
echo "** OK: $DESTDIR!"
else
echo "** ERROR: $DESTDIR not mounted!"; exit 1;
fi

rsync -av --exclude-from=${EXCLUDE} --delete ${SOURCE} ${DESTDIR}

No i tu porażka:


rsync: readlink_stat("/media/sd_backup/etc/shadow") failed: Input/output error (5)
rsync: readlink_stat("/media/sd_backup/etc/resolv.conf") failed: Input/output error (5)
rsync: recv_generator: failed to stat "/media/sd_backup/etc/resolv.conf": Input/output error (5)
rsync: recv_generator: failed to stat "/media/sd_backup/etc/shadow": Input/output error (5)
rsync: recv_generator: failed to stat "/media/sd_backup/etc/network/run/ifstate": Input/output error (5)
rsync: recv_generator: failed to stat "/media/sd_backup/var/lib/urandom/random-seed": Input/output error (5)
rsync: recv_generator: failed to stat "/media/sd_backup/var/log/lastlog": Input/output error (5)
rsync: recv_generator: failed to stat "/media/sd_backup/var/run/dhclient.eth0.pid": Input/output error (5)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1058) [sender=3.0.5]

Trefne pliki (w liczbie sześciu, jak widać) mają długość 0 bajtów, a próba np. ls -li /media/sd_backup/etc/shadow powoduje komunikat I/O error. Usunąć tego też się nie da (rm -f nie daje rady)...

Wobec powyższego, sformatowałem partycję i wykonałem kopię za pomocą następującego polecenia wykorzystując tara:


tar cf - . | (cd /media/sd_backup/; tar xvpf - ) 2> ../../tar.log

Po wsadzeniu kopii zamiast oryginału do Szewy, system wydaje się działać. Czemu rsync zawiódł nie wiem (na razie)...

Dopisane 27 maja 2010 (po południu): Log tara (2> ../../tar.log) zawierał masę wpisów: implausibly old time stamp 1960-04-13 04:17:36. Data jest absurdalna. Żeby było śmieszniej w systemie była inna (w przód 2028 rok -- licznik się przekręcił tarowi?). Pliki z błędnym czasem modyfikacji były głównie w katalogach /dev/ /var/ oraz /etc/; wygląda jakby w czasie inicjalizacji, przed uruchomieniem ntpdate ,,fabryczny'' zegar Szewy wskazywał coś dziwacznego.

Czasy poprawiłem touchem. Zrobiłem rsync na dysk, a potem z dysku na kartę zapasową. Tym razem błędów nie było...

Dopisane 10 Kwietnia 2011: Poprawiłem skrypt rsync_neptune.sh na możliwą okoliczność wykonania kopii z uszkodzonych danych. W nowej wersji tworzone są trzy kopie z dwutygodniowym horyzontem czasowym:


#!/bin/bash
# rsync_neptune.sh (wersja poprawiona)
SOURCE=neptune::wholefs/

EXCLUDE=/root/.rsync/backup_exclude.lst
DESTDIR=/public/sheeva/backup/neptune/rootfs
COPYDIR=/public/sheeva/backup/neptune

### Zachowaj stara kopie pod inna nazwa:
cp -f ${COPYDIR}/1week.tar.gz ${COPYDIR}/2week.tar.gz

### Zachowaj stare dane (sprzed tygodnia):
tar -zcPf ${COPYDIR}/1week.tar.gz ${DESTDIR}

echo "=== Syncing ${SOURCE} at `date` ==="
rsync -av --exclude-from=${EXCLUDE} --delete ${SOURCE} ${DESTDIR}

Powinienem w ciągu dwóch tygodni się połapać, że coś jest nie tak, np. z kartą.

niedziela, 16 maja 2010

MapSource w Linuksie

MapSource firmy Garmin to aplikacja dodawana do każdego odbiornika zdolnego do korzystania z map. Nie ma wersji dla Linuksa, ale działa z emulatorem wine, tyle że przeraźliwie wolno (każda zmiana skali, czy obszaru mapy oznacza czekanie). Zresztą, być może w MSW jest podobnie -- nie sprawdzałem...

Ponieważ ja wykorzystuję MapSource praktycznie wyłącznie do załadowania mapy do urządzenia, powolność działania aż tak bardzo nie przeszkadza. Zatem...

Należy zainstalować MapSource z płyty dostarczonej z urządzeniem. Podłączyć urządzenie kablem USB i sprawdzić czy Linuks go widzi:


$ /sbin/lsusb
Bus 005 Device 003: ID 091e:0003 Garmin International GPSmap (various models)

Można też sprawdzić czy Linuks załadował stosowny moduł:


$ /sbin/lsmod | grep garmin
garmin_gps 18885 0
usbserial 30249 1 garmin_gps
garmin_gps

Jeżeli w powyższych dwóch krokach coś jest nie tak, no to jest problem... Ale u mnie jest OK. Teraz uruchamiamy MapSource:


wine "/home/tomek/.wine/drive_c/Garmin/MapSource.exe"

Jak MapSource nie widzi urządzenia, to trzeba wykonać jeszcze polecenie:


ln -s /dev/ttyUSB0 ~/.wine/dosdevices/com1

Teraz MapSource w mojej Fedorze działa. W Windows XP jak zwykle nie... Pewnie tzw. problem brakujących sterowników.

środa, 12 maja 2010

Amnezja

To były sobie piękne czasy takie
To nawet wtedy papież był Polakiem
Rozmontowaliśmy razem komunę
Lecz po co ja do dzisiaj nie rozumiem

Reszta np.  tutaj.

Dopisane 27 maja 2010 (wieczorem): Dziś pasuje inna zwrotka, mianowicie:
My na monopol mamy prawdę
Ja nie zabijam ani ja nie kradnę
A były przecież kiedyś piękne dni
Gierek, Jaruzel oraz my.

A to w kontekście doniesień medialnych, że niestety sorry ale Ewa Stankiewicz (ta od Trzech Kumpli) już nie jest de mode... Chciałbym żeby powód był taki, że zrobiła po prostu słaby film, ale coś nie potrafię w to uwierzyć...

Sheeva #2

Zainstalowałem Debiana Lenny na karcie SD (Patriot 16Gb class 6) wg. wskazówek ze strony Manually unpacking a tar ball of Debian on SheevaPlug, ale nie poszło gładko. Ponieważ boot loader mojej szewy był w wersji wcześniejszej od zalecanej 3.4.19, zatem kierując się wskazówkami ze strony Upgrading SheevaPlug's U-Boot, rozpocząłem od wgrania nowego U-boata stosując technikę wykorzystującą USB (a nie serwera TFTP). W rezultacie już za pierwszym podejściem zbrikowałem szewę na amen.

Na szczęście się okazało, że wgranie nowego programu rozruchowego i systemu do pamięci NAND nie jest aż takie trudne i sprowadza się do pobrania czegoś co się nazywa SheevaPlug Installer. Relewantna informacja zaczyna się od śródtytułu How to install 1.0?. Należy mianowicie:

  1. pobrać i rozpakować archiwum .tar.gz
  2. przegrać zawartość katalogu installer do katalogu głównego PenDrive'a
  3. w katalogu uboot/uboot-env znaleźć pliki uboot-nand-custom.txt oraz uboot-mmc-custom.txt i poprawić MAC adres odczytując go z obudowy SheevaPlug.
  4. Połączyć SheevaPlug z komputerem za pomocą kabla miniUSB oraz włączyć urządzenie. Z poziomu katalogu głównego instalatora uruchomić program (jako root):

    php ./runme.php nand

    Odczekać aż wszystko się nagra. U mnie nie do końca działa: system się ładuje ale root nie może się zalogować... Pech...

Ponieważ ostatecznie chcę uruchomić system z karty SD, a nie wbudowany z pamięci NAND, to powyższa niedogodność jest w sumie bez znaczenia. Ważne że U-boat jest zaktualizowany do wersji 3.4.19. Można zatem instalować Debiana.

Kartę podzieliłem na partycje i sformatowałem zgodnie z opisem, tyle że zamiast Ext2 użyłem Ext3, co okazało się błędem (ale o tym za chwilę). Następnie pobrałem archiwum z systemem:


wget http://people.debian.org/~tbm/sheevaplug/lenny/base.tar.bz2
wget http://people.debian.org/~tbm/sheevaplug/lenny/base.tar.bz2.asc

Zamontowałem kartę i skopiowałem co trzeba


tar -xjvf ~/base.tar.bz2

Ustawiłem środowisko programu ładującego:


setenv mainlineLinux yes
setenv arcNumber 2097
saveenv
reset

oraz


setenv bootargs_console console=ttyS0,115200
setenv bootargs_root 'root=/dev/mmcblk0p2'
setenv bootcmd_mmc 'mmcinit; ext2load mmc 0 0x01100000 /uInitrd; ext2load mmc 0 0x00800000 /uImage'
setenv bootcmd 'setenv bootargs $(bootargs_console) $(bootargs_root); run bootcmd_mmc; bootm 0x00800000 0x01100000'
saveenv

Teraz run bootcmd i kicha... System nie może odnaleźć partycji systemowej. Próbowałem różnych kombinacji, nic... Wreszcie dla świętego spokoju, sformatowałem kartę jako Ext2 a nie Ext3, tak jak jest to zalecane. Zadziałało... Morał: nie kombinować....

Teraz zrobiłem to wszystko co jest zalecane na stronie Manually unpacking a tar ball of Debian on SheevaPlug, tj.:


rm /etc/ssh/ssh_host*
ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ""
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""

## Synchronizacja czasu
ntpdate pool.ntp.org

apt-get dist-upgrade

## Ustawienie daty/czasu
dpkg-reconfigure tzdata

## wybieram (spacją) pl_PL.utf8 pl_PL.88592, domyślnie pl_PL.utf8
dpkg-reconfigure locales

## zmienić nazwę hosta dodając ją do
vi /etc/hostname

A ponadto:


apt-get install ntp
apt-get install fuse-utils
apt-get install libxml-dom-xpath-perl libxml-dom-perl
apt-get install vim apache2
apt-get install php5 php5-cli
apt-get install make zip unzip

Na razie wystarczy...

Dopisane 20 maja 2010: Na podstawie zaleceń ze strony Debian Lenny -- installing Apache2 and PHP5 doinstalowuję porządnie PHP.

Dopisane 20 maja 2010: Formatowanie karty 8Gb za pomocą gparted. Partycja #1: 102 Mb (boot), partycja #2: 7044 Mb (system), partycja #3: ok. 500 Mb (swap). Za pomocą fdiska dodałem flagę boot do pierwszej partycji:


/sbin/fdisk /dev/sdc
a # toggle a bootable flag
1 # pierwsza partycja
w # zapisz tabelę partycji

Wczoraj próbowałem kartę SDHC Patriot LX (klasa 10), ale przesadziłem:


SDHC found. Card desciption is:
Manufacturer: 0x27, OEM "PH"
Product name: "SD08G", revision 3.0
Serial number: 2952790466
Manufacturing date: 4/2010
CRC: 0x00, b0 = 0

** Unable to read "/uInitrd" from mmc 0:1 **

** Unable to read "/uImage" from mmc 0:1 **
## Booting image at 00800000 ...
Bad Magic Number

Wygląda że Patriot LX 8Gb (class 10) is one of them, czyli z gatunku tych z którymi U-boat nie działa.

Ładowanie filmów na YouTube off-line

Ponieważ opisany poprzednio uploader filmów na YT przestał działać przyjrzałem się bliżej skryptowi youtube-upload.py. Od pierwszego strzału nie działa, ale... Skrypt ten wymaga do działania programu ffmpeg, który to program służy wyłącznie do obliczenia czasu trwania filmu. W przypadku szewy uruchamianie ffmpeg chyba nie jest dobrym pomysłem, a uruchamianie tylko po to żeby obliczyć ile trwa film to w ogóle beznadziejna sprawa...

Zatem ,,rozbroiłem'' skrypt, wpisując na zicher w odpowiednie miejsce długość filmu jako 60 (pewnie sekund):


def get_video_duration(video_path):
"""Return video duration in seconds."""
#errdata = ffmpeg("-i", video_path)
#match = re.search(r"Duration:\s*(.*?),", errdata)
#if not match:
# return
#strduration = match.group(1)
#return sum(factor*float(value) for (factor, value) in
# zip((60*60, 60, 1), strduration.split(":")))
return 60

Wygląda że działa.... Opis filmu dodaję po załadowaniu... Skrypt youtube-upload.py korzysta z API jest zatem dużo większa szansa, że nagle przestanie działać (jak to było z poprzednio wykorzystywanym programem). Do działania potrzebna jest też biblioteka python-gdata, która wszakże zainstalowała się na szewie w/o problems.

wtorek, 11 maja 2010

Poprawienie błędnej data/czasu wykonania zdjęcia

Jak zmienić błędny czas wykonania serii zdjęć, co się może zdarzyć gdy zapomni się ustawić zegar w aparacie? Wykorzystując exiftool jest to bardzo proste. Należy umieścić wszystkie trefne pliki w pewnym katalogu a następnie wykonać polecenie:


exiftool "-DateTimeOriginal+=5:6:21 10:18:20" katalog

lub lepiej:


exiftool -AllDates-=1 katalog
exiftool -AllDates-=11:20:11 katalog

Pierwsze przesunie (w każdym pliku) datę wykonania zdjęcia (DateTimeOriginal) o 5 lat, 6 miesięcy, 21 dni, 10 godzin, 18 minut oraz 20 sekund w przód. Drugie polecenie przesuwa o godzinę do tyłu wartości trzech pól: DateTimeOriginal, CreateDate oraz ModifyDate. Trzecie przesuwa tak samo jak drugie, tylko przesuwa o 11 godzin, 20 minut oraz 11 sekund.

Manipulowanie wpisami EXIF jest dobrze opisane w dokumentacji, exiftool więc to co powyżej nie jest żadną rewelacją.

Dziś usiłowałem w ten sposób poprawić czas zdjęć zrobionych aparatem z nie ustawionym zegarem (same zera w dacie/czasie). I się nie dało, tzn.


exiftool "-DateTimeOriginal+=2010:5:11 16:00:00" katalog

Zwracał błąd (że miesiąc ma numer -1). Zadziałało za to:


exiftool "-DateTimeOriginal=2010:5:11 16:00:00" katalog

tj. bez plusa przed znakiem równości

Przy okazji: The Olympus file format is Pmddnnnn.jpg where: m is month 1-9A-C, dd is day 0--31, nnnn is number 0000-9999. The P is fixed for all Olympus Cameras. Z tego by wynikało, że moje przekonanie, że nazwy plików się nie powtarzają nie jest oparte na prawdzie.

środa, 5 maja 2010

Wycieczka do Wilna

W tym roku w tzw. długi weekend pojechaliśmy na wycieczkę (samochodem) na Litwę, a konkretnie w zamiarze zwiedzania Wilna i Troków.

Ślady GPX z wycieczki są tutaj: 20100430201005012010050220100503. Więcej zdjęć jest na flickr.com. Ślady w formacie KML są tutaj: 20100430201005012010050220100503.