1+ #!/usr/bin/python
2+ # Copyright Josh Gachnang 2010
3+ # Release under the New BSD License
4+ # ServerCobra.com
5+
6+ # Based off http://www.straw-dogs.co.uk/12/10/python-virtual-host-creator/
7+
8+ import getopt
9+ import os
10+ import subprocess
11+ import sys
12+ from random import randint , choice
13+ import string
14+
15+ def main (argv ):
16+
17+ try :
18+ opts , args = getopt .getopt (argv , "hd:a:" , ["help" , "domain=" ])
19+ except getopt .GetoptError :
20+ usage ()
21+ sys .exit (2 )
22+
23+ if len (opts ) == 0 :
24+ usage ()
25+ sys .exit (2 )
26+
27+ for o , a in opts :
28+ if o in ("-h" , "--help" ):
29+ usage ()
30+ sys .exit ()
31+ if o in ("-d" , "--domain" ):
32+ domain = a
33+ normalize_domain = domain .replace ("." , "__" )
34+ else :
35+ assert False , "unhandled option"
36+
37+
38+ #if not os.path.isdir("/var/www/%s" % directory):
39+ # os.mkdir("/var/www/%s" % directory)
40+
41+ #if not os.path.isdir("/var/www/%s/htdocs" % directory):
42+ # os.mkdir("/var/www/%s/htdocs" % directory)
43+
44+ default_vhost_template = """
45+ <VirtualHost *:80>
46+ ServerName __DOMAIN__
47+ ServerAlias www.__DOMAIN__
48+
49+
50+ #Log files
51+ CustomLog /home/__NORM_DOM__/__NORM_DOM__/logs/access.log combined
52+ ErrorLog /home/__NORM_DOM__/__NORM_DOM__/logs/error.log
53+
54+ ErrorDocument 404 /404.html
55+ ErrorDocument 401 /401.html
56+ ErrorDocument 500 /500.html
57+
58+ DocumentRoot /home/__NORM_DOM__/__NORM_DOM__/htdocs
59+ <Directory /home/__NORM_DOM__/__NORM_DOM__/htdocs >
60+ Options +Indexes +FollowSymlinks +ExecCGI +Includes -MultiViews
61+ AllowOverride All
62+ Order Allow,Deny
63+ Allow from all
64+ </directory>
65+
66+ </virtualhost>
67+ """
68+
69+ django_vhost_template = """
70+ <VirtualHost *:80>
71+ ServerName __DOMAIN__
72+ ServerAlias www.__DOMAIN__
73+
74+
75+ #Log files
76+ CustomLog /home/__NORM_DOM__/__NORM_DOM__/logs/access.log combined
77+ ErrorLog /home/__NORM_DOM__/__NORM_DOM__/logs/error.log
78+
79+ ErrorDocument 404 /404.html
80+ ErrorDocument 401 /401.html
81+ ErrorDocument 500 /500.html
82+
83+ DocumentRoot /home/__NORM_DOM__/__NORM_DOM__/htdocs
84+ <Directory /home/__NORM_DOM__/__NORM_DOM__/htdocs >
85+ Options +Indexes +FollowSymlinks +ExecCGI +Includes -MultiViews
86+ AllowOverride All
87+ Order Allow,Deny
88+ Allow from all
89+ </directory>
90+
91+ Alias /static /home/__NORM_DOM__/__NORM_DOM__/__APP__/static/
92+ <Location "/static">
93+ Order allow,deny
94+ Allow from all
95+ </Location>
96+
97+ Alias /media/ /usr/lib/python-django/django/contrib/admin/media/
98+ <Location "/media/">
99+ SetHandler None
100+ Order allow,deny
101+ Allow from all
102+ </Location>
103+
104+ #Start mod_wsgi
105+ WSGIScriptAlias / /home/__NORM_DOM__/__NORM_DOM__/__APP__/apache/wsgi_handler.py
106+ <Directory "/home/__NORM_DOM__/__NORM_DOM__/__APP__/apache">
107+ Order allow,deny
108+ Allow from all
109+ </Directory>
110+
111+ WSGIDaemonProcess __NORM_DOM__ user=__NORM_DOM__ group=__NORM_DOM__ processes=2 threads=10
112+ WSGIProcessGroup __NORM_DOM__
113+
114+ </virtualhost>
115+ """
116+
117+
118+ vhost = vhost_template .replace ('__DOMAIN__' , domain ).replace ('__NORM_DOM__' , normalize_domain )
119+
120+ open ('/etc/apache2/sites-available/%s.conf' % directory , 'w' ).write (vhost )
121+ os .system ('a2ensite %s.conf' % directory )
122+ os .system ('/etc/init.d/apache2 reload' )
123+
124+ # Characters to be used while generating password
125+ chars = string .ascii_letters + string .digits + "!#$&"
126+
127+ def random_password (length ):
128+ return "" .join (choice (chars ) for x in range (randint (length , length )))
129+
130+ def usage ():
131+ print 'usage: newv.py [-d domain.com]'
132+ print ' Please exclude the "www" at the front of the domain'
133+
134+ def run (arg ):
135+ """
136+ Runs the given arg at the command line using the default shell. Outputs
137+ when commands are run successfully.
138+
139+ Based on http://developer.spikesource.com/wiki/index.php/How_to_invoke_subprocesses_from_Python
140+
141+ @param Tuple args
142+ A tuple of args, with the first being the command to be run, and
143+ the remaining ones flags and arguments for the command. STDOUT and
144+ STDERR are piped to tuple, waiting until the output is finished,
145+ then writing both to the log files, if not empty.
146+ Ex. ['apt-get', '-y', 'install', 'dnsmasq'], which installs
147+ dnsmasq using apt-get, and assumes yes to questions.
148+ """
149+
150+ # Open output and write some info about the command to be written, including
151+ # name of command and arguments.
152+ # This could be modified to adjust how much is printed via a DEBUG variable.
153+ with open (os .path .join (os .curdir , "output.log" ), 'a' ) as outFile :
154+ outFile .write ("Command: " )
155+ for a in arg :
156+ outFile .write (a ,)
157+ outFile .write (" " )
158+ outFile .write ("\n " )
159+ # Open output and error log file and append to them the output of the commands
160+ with open (os .path .join (os .curdir , "output.log" ), 'a' ) as outFile :
161+ with open (os .path .join (os .curdir , "error.log" ), 'a' ) as errorFile :
162+ # Call the subprocess using convenience method
163+
164+ retval = subprocess .call (arg , - 1 , None , None , outFile , errorFile )
165+ # Check the process exit code, print error information if it exists
166+ if not retval == 0 :
167+ errData = errorFile .read ()
168+ raise Exception ("Error executing command: " + repr (errData ))
169+
170+ if __name__ == "__main__" :
171+ main (sys .argv [1 :])
0 commit comments