среда, 18 июля 2012 г.

Создание сайта из шаблона, пользователя и БД

Работа с башем, MySQL-ем.
Скрипт по переданным ему параметрам создает БД, пользователя в системе и в БД, берет шаблоны сайтов nginx-а и apache и на основании их создает conf-файлы.


#!/bin/bash

# Create database
/usr/bin/mysql -u root -pXXXXX -e 
   "CREATE DATABASE "$1" CHARACTER SET utf8 COLLATE utf8_general_ci;"
# Create database user
/usr/bin/mysql -u root -pXXXXX -e 
   "CREATE USER '"$2"'@'localhost' IDENTIFIED BY '"$3"' ;"
/usr/bin/mysql -u root -pXXXXX -e 
   "GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON "$1".* TO '"$2"'@'localhost' ;"

# Create directories
/bin/mkdir /var/www/vhosts/$4
/bin/mkdir /var/www/vhosts/$4/www/
/bin/mkdir /var/www/vhosts/$4/tmp/
/bin/mkdir /var/www/vhosts/$4/cgi/

# Create system user
/usr/sbin/useradd -b /var/www/vhosts/$4 -g www-data -s /bin/bash $2
/bin/echo $2:$3|/usr/sbin/chpasswd
/bin/chown -R $2:www-data /var/www/vhosts/$4

# Create conf files from template
/bin/bash -c "/bin/sed -e 's/CHANGEME/"$4"/g' 
   /etc/httpd/sites-available/template > /etc/httpd/sites-available/"$4
/bin/ln -s /etc/httpd/sites-available/$4 /etc/httpd/sites-enabled/$4
/bin/bash -c "/bin/sed -e 's/CHANGEME/"$4"/g' 
   /etc/nginx/sites-available/template > /etc/nginx/sites-available/"$4
/bin/ln -s /etc/nginx/sites-available/$4 /etc/nginx/sites-enabled/$4


вызывать его надо примерно так:

[root@localhost]# script.sh DBName username password sitename.com

воскресенье, 8 июля 2012 г.

sed и cut за работой

Чтоб не забыть или потерять.
Задача: есть файл с настройками DNS-зон, из него надо выдергивать названия этих зон и по ним создавать конфиг для nginx-а из шаблона.
Готовый результат:


#!/bin/bash

for i in $(grep 'zone' /etc/named/conf.local | sed -e 's/zone "//g' | sed -e 's/" {//g')
do
  echo $i
  if ! [ -e /etc/nginx/sites-available/$i ]; then
    /bin/bash -c "/bin/sed -e 's/CHANGEME/"$i"/g' 
     /etc/nginx/sites-available/template > /etc/nginx/sites-available/"$i
    /bin/ln -s /etc/nginx/sites-available/$i /etc/nginx/sites-enabled/$i
  fi
done;
/etc/init.d/nginx restart
 

Самый большой интерес представляет первая строчка, которая в for. Вот ее же вариант, только с использованием cut. Спасибо за помощь Грузину!

grep 'zone' conf.local | cut -d " " -f 2 | cut -d "\"" -f 2
 

Еще надо на awk сделать для коллекции.

понедельник, 14 мая 2012 г.

Падение интерфейса

Чтоб не забыть что я делал и где искал:
На сервере ASUS Z8NR-D12 при большом потоке трафика отваливается сетевой интерфейс Intel 82574L.
В момент перед потерей коннекта top показывает:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15 root 20 0 0 0 0 R 55.8 0.0 138:19.63 ksoftirqd/2
19 root 20 0 0 0 0 R 55.8 0.0 169:28.29 ksoftirqd/3
35 root 20 0 0 0 0 R 55.8 0.0 135:13.21 ksoftirqd/7
31 root 20 0 0 0 0 R 55.5 0.0 151:44.32 ksoftirqd/6
23 root 20 0 0 0 0 S 54.8 0.0 152:04.43 ksoftirqd/4
27 root 20 0 0 0 0 S 54.2 0.0 28:23.75 ksoftirqd/5
3 root 20 0 0 0 0 S 52.8 0.0 161:36.75 ksoftirqd/0

То есть ksoftirqd забивает память и съедает все процессорное время. Помогал только ребут.

Решение нашел здесь.
Правда предлагалось добавить репозиторий отсюда. Но для моей федоры 16 он не подошел бы, поэтому я скачал дрова с sourceforge.
Берем дрова, распаковываем, читаем README и делаем все по Installation.
В /etc/modprobe.d создал файл eth.conf с содержимым

# new network driver
alias em1 e1000e
alias em2 e1000e

пятница, 4 мая 2012 г.

Ротация логов

Клевый скрипт. И он работает! Особенности:
1) ротация проходит по интервалу в днях,
2) в названии файлов используется год-месяц-день, то есть ротация по имени, а не по времени создания файла (хотя и это сделать можно)
3) для каждой папки надо создавать 3 записи в settings.ini: откуда, куда и маска файлов
4) в settings.ini используются названия fromN toN maskN, где N число
Вобщем вот пример settings.ini

[local]
logfile = Rotation.log

[copy]
dayinterval = 11
count = 3

from1 = D:\Router_xxx_xx_x_x\abonent\
to1 = K:\Router_xxx_xx_x_x\abonent\
mask1 = NF_%Y_%m_%d

from2 = D:\Router_xxx_xx_x_x\authorize\
to2 = K:\Router_xxx_xx_x_x\authorize\
mask2 = NF_%Y_%m_%d

from3 = D:\NAS_xxx-xx-xx-xx\
to3 = K:\NAS_xxx-xx-xx-xxx\
mask3 = %Y-%m-%d


В скрипте маленькая функция, которая архивирует файлики

### Archive and remove
def arch (filename, archivename, isrm):
        if not os.path.exists (os.path.dirname (archivename)):
                os.makedirs (os.path.dirname (archivename))
        try:
                os.chdir (os.path.dirname (archivename))
                fout = gzip.open (os.path.basename(archivename), 'wb')
        except IOError:
                print ('Error creating archive file')
                return
        fin = open (filename, 'rb')                                
        fout.writelines (fin)
        fout.close()
        fin.close()
        if isrm:
                os.remove (filename)


А вот сам скрипт

###   MAIN        
if __name__ == '__main__':
        import gzip
        import configparser
        import time
        import re
        import os
        from datetime import date
        from datetime import timedelta

        cfg = configparser.RawConfigParser()
        cfg.read ('settings.ini')
        logfile = open (cfg.get ('local', 'logfile'), 'a')
        logfile.writelines (time.strftime 
        ("\n[%Y-%m-%d %H:%M:%S] ") +'Service starts')
        dayinterval = cfg.get ('copy', 'dayinterval')
        date_from = date.today() - timedelta (days=int(dayinterval))
        cnt = cfg.get ('copy', 'count')
        i = 1
        while i <= int(cnt) :
                dir_from = cfg.get ('copy', 'from'+str(i))
                dir_to = cfg.get ('copy', 'to'+str(i))+
                date_from.strftime ("%Y-%m\\")
                filemask = cfg.get ('copy', 'mask'+str(i))
                datemask = date_from.strftime (filemask)
                mask = re.compile (datemask, re.IGNORECASE)
                flist = filter (mask.search, os.listdir(dir_from))
                for f in flist:
                        logfile.writelines (time.strftime 
                        ("\n[%Y-%m-%d %H:%M:%S] ") + dir_from+f)
                        arch (dir_from+f, dir_to+f+'.gz',True)
                i = i + 1
        logfile.writelines (time.strftime 
        ("\n[%Y-%m-%d %H:%M:%S] ") +'Service ends')
        logfile.close()



UPD: приделал раскладывание файлов по месяцам.

среда, 18 апреля 2012 г.

Проверка доступности сервера.

Есть у меня один сервер, который ведет себя не по-мужски, отваливается и не сообщает об этом. Поэтому надо его мониторить.
Уверен, что поиск даст 100500 вариантов мониторинга, но мне надо было сделать быстро и чтоб работало.
Итак, снова питон:

from ftplib import FTP
import smtplib

try :
    ftp = FTP('hostname.com')
    ftp.close()
except :
    print ('error')
    server = smtplib.SMTP('smtpserver.com')
    server.set_debuglevel(1)
    msg = 'Subject: ALARM!\nFrom: alert@smtpserver.com\n
    To: arakelov.az@smtpserver.com\n\n'
    server.sendmail('alert@smtpserver.com',
    'arakelov.az@smtpserver.com', msg+'\nServer is not responding')
    server.quit()


Если не получается зайти по FTP, то шлем письмо, что не отвечает.
Тут используется отправка почты без аутентификации, ну у меня так и есть.
Скрипт в кроне отрабатывает каждый час.

четверг, 12 апреля 2012 г.

Создание полной структуры каталогов

Наконец-то!
Как же давно я хотел написать эту функцию!
Функция создает полную структуру каталогов из входной строки. Допустим, мы собираемся копировать файл из папки C:\temp в папку D:\dir1\dir2\dir3\ а на диске D нет даже dir1
Итак, вот она


def makedirectory (dirname):
        start = dirname.find('\\')+1 #здесь мы пропускаем название диска
        i = 1
        while i < dirname.count('\\') :
                try :
                        os.mkdir (dirname[0:dirname.find('\\',start)])
                except :
                        print ('exists')
                finally :
                        start = dirname.find('\\',start)+1
                        i = i + 1