merge master into grid-computing-merge
[slapos.git] / slapos / recipe / apachephp / __init__.py
1 ##############################################################################
2 #
3 # Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
4 #
5 # WARNING: This program as such is intended to be used by professional
6 # programmers who take the whole responsibility of assessing all potential
7 # consequences resulting from its eventual inadequacies and bugs
8 # End users who are looking for a ready-to-use solution with commercial
9 # guarantees and support are strongly adviced to contract a Free Software
10 # Service Company
11 #
12 # This program is Free Software; you can redistribute it and/or
13 # modify it under the terms of the GNU General Public License
14 # as published by the Free Software Foundation; either version 3
15 # of the License, or (at your option) any later version.
16 #
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #
26 ##############################################################################
27 import shutil
28 import os
29 import signal
30 from binascii import b2a_uu as uuencode
31
32 from slapos.recipe.librecipe import GenericBaseRecipe
33
34 class Recipe(GenericBaseRecipe):
35
36 def __init__(self, buildout, name, options):
37 self.environ = {}
38
39 environment_section = options.get('environment-section', '').strip()
40 if environment_section and environment_section in buildout:
41 # Use environment variables from the designated config section.
42 self.environ.update(buildout[environment_section])
43 for variable in options.get('environment', '').splitlines():
44 if variable.strip():
45 try:
46 key, value = variable.split('=', 1)
47 self.environ[key.strip()] = value
48 except ValueError:
49 raise zc.buildout.UserError('Invalid environment variable definition: %s', variable)
50 # Extrapolate the environment variables using values from the current
51 # environment.
52 for key in self.environ:
53 self.environ[key] = self.environ[key] % os.environ
54
55 return GenericBaseRecipe.__init__(self, buildout, name, options)
56
57 def install(self):
58 path_list = []
59
60 # Copy application if not already existing
61 htdocs_location = self.options['htdocs']
62 if not (os.path.exists(htdocs_location) and os.listdir(htdocs_location)):
63 try:
64 os.rmdir(htdocs_location)
65 except:
66 pass
67 shutil.copytree(self.options['source'], htdocs_location)
68
69 # Install php.ini
70 php_ini = self.createFile(os.path.join(self.options['php-ini-dir'],
71 'php.ini'),
72 self.substituteTemplate(self.getTemplateFilename('php.ini.in'),
73 dict(tmp_directory=self.options['tmp-dir']))
74 )
75 path_list.append(php_ini)
76
77 # Install apache
78 if self.optionIsTrue('default-conf', True):
79 apache_config = dict(
80 pid_file=self.options['pid-file'],
81 lock_file=self.options['lock-file'],
82 ip=self.options['ip'],
83 port=self.options['port'],
84 error_log=self.options['error-log'],
85 access_log=self.options['access-log'],
86 document_root=self.options['htdocs'],
87 php_ini_dir=self.options['php-ini-dir'],
88 )
89 httpd_conf = self.createFile(self.options['httpd-conf'],
90 self.substituteTemplate(self.getTemplateFilename('apache.in'),
91 apache_config)
92 )
93 path_list.append(httpd_conf)
94
95 wrapper = self.createWrapper(name=self.options['wrapper'],
96 command=self.options['httpd-binary'],
97 parameters=[
98 '-f',
99 self.options['httpd-conf'],
100 '-DFOREGROUND'
101 ],
102 env=self.environ)
103 path_list.append(wrapper)
104
105 secret_key_filename = os.path.join(self.buildout['buildout']['directory'],
106 '.php_secret_key')
107 if not os.path.exists(secret_key_filename):
108 secret_key = uuencode(os.urandom(45)).strip()
109 # Remove unsafe characters
110 secret_key = secret_key.translate(None, '"\'\\')
111 with open(secret_key_filename, 'w') as secret_key_file:
112 secret_key_file.write(secret_key)
113 else:
114 with open(secret_key_filename, 'r') as secret_key_file:
115 secret_key = secret_key_file.read()
116
117 # Generate application configuration file
118 if self.options.get('template'):
119 application_conf = dict(mysql_database=self.options['mysql-database'],
120 mysql_user=self.options['mysql-username'],
121 mysql_password=self.options['mysql-password'],
122 mysql_host='%s:%s' % (self.options['mysql-host'],
123 self.options['mysql-port']),
124 mysql_ip=self.options['mysql-host'],
125 mysql_port=self.options['mysql-port'],
126 secret_key=secret_key,
127 )
128
129 directory, file_ = os.path.split(self.options['configuration'])
130
131 path = self.options['htdocs']
132 if directory:
133 path = os.path.join(path, directory)
134 if not os.path.exists(path):
135 os.makedirs(path)
136 if not os.path.isdir(path):
137 raise OSError("Cannot create %r." % path)
138
139 destination = os.path.join(path, file_)
140 config = self.createFile(destination,
141 self.substituteTemplate(self.options['template'], application_conf))
142 path_list.append(config)
143
144 #if os.path.exists(self.options['pid-file']):
145 # # Reload apache configuration
146 # with open(self.options['pid-file']) as pid_file:
147 # pid = int(pid_file.read().strip(), 10)
148 # try:
149 # os.kill(pid, signal.SIGUSR1) # Graceful restart
150 # except OSError:
151 # pass
152 return path_list