Занимаюсь разработкой сайтов и всякие эксперименты и основную разработку делаю на локальном компьютере под Debian. В следствии того, что приходилось постоянно ручками создавать виртуальные хосты пришлось поставить себе цель автоматизировать процесс.
Первый делом двинулся я в просторы интернета в поисках необходимого решения, которое должно было обладать простотой и выполнять всего 2 задачи: добавлять виртуальный хост и удалять его. Мне удобно пользоваться консолью, поэтому и приложение должно было быть консольным. Но все варианты которые нашел имели большое количество ненужного функционала, кроме того почти все они предоставляли web интерфейс, которым я просто не хотел пользоваться.
В результате были поставлены цели:
— написать свой простенький скрипт, который создавал все то, что мне нужно;
— в качестве языка разработке я выбрал python, т.к. давно искал повод на нем учится писать.
Update (08.09.11 20:25): учитывая ошибки в комментариях немного исправил скрипт. Начал использовать optparse, сократил использование .write.
В результате я получил полностью удовлетворяющий меня скриптпод катом.
В связи с предназначением скрипта, он запускается под root`om или через sudo.
Мини инструкция, для тех кто не дойдет до -help:
Usage: script [options] [add|drop] domain
В опциях изменяются настройки для работы скрита.
Во время добавления либо удаления домена:
— вносится изменение в hosts файл, для внесении информации о домене;
— в директориях переданных через dir_site создаются необходимые файлы и папки для нашего домена;
— в директории указанной в apache_config_site создается файл с конфигурацией virtualhost для apache.
В связи с тем, что это мой первый опыт написания Python скрипта, очень хочу, чтоб максимально критически отнеслись к моим ошибкам или к неправильному подходу (особенно благодарен буду заподжопник пинок в нужное направление).
Первый делом двинулся я в просторы интернета в поисках необходимого решения, которое должно было обладать простотой и выполнять всего 2 задачи: добавлять виртуальный хост и удалять его. Мне удобно пользоваться консолью, поэтому и приложение должно было быть консольным. Но все варианты которые нашел имели большое количество ненужного функционала, кроме того почти все они предоставляли web интерфейс, которым я просто не хотел пользоваться.
В результате были поставлены цели:
— написать свой простенький скрипт, который создавал все то, что мне нужно;
— в качестве языка разработке я выбрал python, т.к. давно искал повод на нем учится писать.
Update (08.09.11 20:25): учитывая ошибки в комментариях немного исправил скрипт. Начал использовать optparse, сократил использование .write.
В результате я получил полностью удовлетворяющий меня скрипт
#!/usr/bin/env python
# -*- coding: utf-8 -*-
###
# Скрипт предназначен для легкого управления локальными доменами
###
import os, sys, re, shutil, string, pwd, grp, stat
from optparse import OptionParser
# Проверяем права администратора, если нет, то выводим предупреждение
# т.к. правка системных файлов не возможно без соответствующих прав доступа
# и приведет к ошибкам
if os.getuid()!=0:
sys.exit ("\033[31mСкрипт должен работать с правами администратора!\033[0m");
# Название скрипта
sname=os.path.basename(__file__);
def main():
parser = OptionParser(usage="usage: %prog [options] [add|drop] domain",
version="%prog 1.0")
parser.add_option("-d", "--dir_site", default="/home/alen/domains/",
metavar="/home/alen/domains/", help=u"Директория для домена.");
parser.add_option("-a", "--apache_bin", default="/etc/init.d/apache2",
metavar="/etc/init.d/apache2", help=u"Бинарник apache для рестарта.");
parser.add_option("-c", "--apache_config_site",
default="/etc/apache2/sites-enabled/", metavar="/etc/apache2/sites-enabled/",
help=u"Директория sites-enabled от apache для настроек virtualhost.");
parser.add_option("-t", "--host", default="/etc/hosts", metavar="/etc/hosts",
help=u"Системный файл hosts для внесения информации о домене.");
parser.add_option("-i", "--ip", default="127.0.0.1", metavar="127.0.0.1",
help=u"IP для сайта");
parser.add_option("-e", "--a2ensite", default="a2ensite", metavar="a2ensite",
help=u"enable an apache2 site / virtual host");
(options, args) = parser.parse_args();
if len(args)!=2 or not args[0] in {"add":1,"drop":2}:
parser.error(sname+" -h");
return {"options":options,"args":args};
conf=main();
options=conf['options'];
# Получаем группу и пользователя права которого будут для папки
# Возьмем их из папки в которую все сложим: dir_site
stat_info = os.stat(options.dir_site);
options.uid = stat_info.st_uid;
options.gid = stat_info.st_gid;
options.user = pwd.getpwuid(options.uid)[0];
options.group = grp.getgrgid(options.gid)[0];
# Функция удаления строки из файла
def remove_string(filename, string):
rst = [];
with open(filename) as fd:
t = fd.read();
for line in t.splitlines():
if line != string:
rst.append(line);
with open(filename, 'w') as fd:
fd.write('\n'.join(rst))
fd.write('\n')
def apache_site_config(name):
file_name=options.apache_config_site+name;
dir_site=options.dir_site+name;
f = open(file_name,"w+");
print >> f, '<VirtualHost *:80>\n\n'+\
'DocumentRoot '+ dir_site +'/www\n'+\
'ServerAlias www.'+name+'\n'+\
'ServerName '+name+'\n'+\
'ScriptAlias /cgi-bin/ '+dir_site+'/www/cgi-bin/\n\n'+\
'<Directory "'+dir_site+'/www">\n'+\
'\tAllowOverride All\n'+\
'\tOrder Deny,Allow\n'+\
'\tAllow from all\n'+\
'\tOptions All\n'+\
'</Directory>\n\n'+\
'<Directory "'+dir_site+'/www/cgi-bin/">\n'+\
'\tAllowOverride None\n'+\
'\tOptions +ExecCGI -MultiViews +SymLinksIfOwnerMatch\n'+\
'\tOrder allow,deny\n'+\
'\tAllow from all\n'+\
'</Directory>\n\n'+\
'<IfModule dir_module>\n'+\
'\tDirectoryIndex index.php index.html index.cgi\n'+\
'</IfModule>\n\n'+\
'#SuexecUserGroup '+options.user+' '+options.group+'\n'+\
'ErrorLog \"'+ dir_site +'/log/error.log\"\n'+\
'CustomLog \"'+ dir_site +'/log/access.log\" combined\n'+\
'LogLevel warn\n\n'+\
'</VirtualHost>';
f.close();
# Функция добавления домена
def add_domain(name):
dir_site=options.dir_site+name;
if os.path.exists(dir_site):
sys.exit("Сайт "+name+" не может быть записан в "+dir_site);
elif os.path.exists(options.apache_config_site+name):
sys.exit(options.apache_config_site+name+" - Занят конфигурационный файл!");
else:
os.makedirs(dir_site+"/");
os.makedirs(dir_site+"/www/");
os.makedirs(dir_site+"/www/cgi-bin/");
os.makedirs(dir_site+"/log/");
f = open(dir_site+"/www/index.php","a+");
f.write('<?php\nphpinfo();');
f.close();
f = open(dir_site+"/www/cgi-bin/index.cgi","a+");
print >> f,'#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n'+\
'import cgitb\ncgitb.enable()\n\n'+\
'print "Content-Type: text/plain;charset=utf-8"\n'+\
'print\n\nprint "Hello World!"';
f.close();
os.system("chown -R "+options.user+":"+options.group+" "+dir_site);
os.chmod(dir_site+"/www/cgi-bin/index.cgi", 0755);
apache_site_config(name);
f = open(options.host,"a+");
f.write("\n"+options.ip+"\t"+name+"\twww."+name);
f.close();
f = open(dir_site+"/www/.htaccess","a+");
f.write("AddDefaultCharset UTF-8");
f.close();
os.system(options.a2ensite+" "+name);
os.system(options.apache_bin+" restart");
sys.exit("\033[31mДомен http://"+name+" успешно создан\033[0m");
pass;
# Функция удаления домена
def drop_domain(name):
dir_site=options.dir_site+name;
if os.path.exists(dir_site):
shutil.rmtree(dir_site);
if os.path.exists(options.apache_config_site+name):
os.unlink(options.apache_config_site+name);
remove_string(options.host, options.ip+"\t"+name+"\twww."+name);
os.system(options.apache_bin+" restart");
sys.exit("\033[31mУпоминания о домене "+name+" удалены!\033[0m");
pass;
if conf["args"][0] in {"add":1,"drop":2} and \
re.compile('^[-\w.]{3,}$').match(conf["args"][1]):
if conf["args"][0]=='add':
add_domain(conf["args"][1]);
else:
drop_domain(conf["args"][1]);
else:
sys.exit("\033[31mКоманды \"" + conf["args"][0] + "\" не существует!\033[0m");
Примечания к скрипту
В связи с предназначением скрипта, он запускается под root`om или через sudo.
Мини инструкция, для тех кто не дойдет до -help:
Usage: script [options] [add|drop] domain
В опциях изменяются настройки для работы скрита.
Во время добавления либо удаления домена:
— вносится изменение в hosts файл, для внесении информации о домене;
— в директориях переданных через dir_site создаются необходимые файлы и папки для нашего домена;
— в директории указанной в apache_config_site создается файл с конфигурацией virtualhost для apache.
Пользуясь моментом
В связи с тем, что это мой первый опыт написания Python скрипта, очень хочу, чтоб максимально критически отнеслись к моим ошибкам или к неправильному подходу (особенно благодарен буду за