paulb@572 | 1 | #!/usr/bin/env python |
paulb@572 | 2 | |
paulb@572 | 3 | "Make a configuration file for an Apache-resident application." |
paulb@572 | 4 | |
paulb@572 | 5 | import os, sys |
paulb@572 | 6 | import glob |
paulb@572 | 7 | |
paulb@572 | 8 | class ApacheServer: |
paulb@572 | 9 | def __init__(self, apache_site_dir): |
paulb@572 | 10 | self.apache_site_dir = apache_site_dir |
paulb@572 | 11 | self.directories = [apache_site_dir, os.path.split(apache_site_dir)[0]] |
paulb@572 | 12 | |
paulb@572 | 13 | def get_user_from_config(self): |
paulb@572 | 14 | return self.get_item_from_config("User") |
paulb@572 | 15 | |
paulb@572 | 16 | def get_server_root_from_config(self): |
paulb@572 | 17 | return self.get_item_from_config("ServerRoot") |
paulb@572 | 18 | |
paulb@572 | 19 | def get_item_from_config(self, item_name): |
paulb@572 | 20 | item = None |
paulb@572 | 21 | for apache_dir in self.directories: |
paulb@572 | 22 | for conf_filename in glob.glob(os.path.join(apache_dir, "*.conf")): |
paulb@572 | 23 | conf_file = open(conf_filename) |
paulb@572 | 24 | for line in conf_file.readlines(): |
paulb@572 | 25 | line_parts = self.parse_line(line) |
paulb@572 | 26 | if len(line_parts) > 1 and line_parts[0] == item_name: |
paulb@572 | 27 | item = line_parts[1] |
paulb@572 | 28 | conf_file.close() |
paulb@572 | 29 | return item |
paulb@572 | 30 | conf_file.close() |
paulb@572 | 31 | return None |
paulb@572 | 32 | |
paulb@572 | 33 | def parse_line(self, line): |
paulb@572 | 34 | parts = line.split('"') |
paulb@572 | 35 | new_parts = [] |
paulb@572 | 36 | for i in range(0, len(parts)): |
paulb@572 | 37 | part = parts[i] |
paulb@572 | 38 | if i % 2 == 0: |
paulb@572 | 39 | new_parts += part.split() |
paulb@572 | 40 | else: |
paulb@572 | 41 | new_parts.append(part) |
paulb@572 | 42 | return new_parts |
paulb@572 | 43 | |
paulb@572 | 44 | cgi_template = """ |
paulb@572 | 45 | ScriptAlias %s "%s" |
paulb@572 | 46 | """ |
paulb@572 | 47 | |
paulb@572 | 48 | mod_python_template = """ |
paulb@572 | 49 | <Location "%s"> |
paulb@572 | 50 | SetHandler python-program |
paulb@572 | 51 | PythonHandler %s |
paulb@572 | 52 | PythonDebug On |
paulb@572 | 53 | PythonPath "['%s'] + sys.path" |
paulb@572 | 54 | </Location> |
paulb@572 | 55 | """ |
paulb@572 | 56 | |
paulb@572 | 57 | if __name__ == "__main__": |
paulb@572 | 58 | try: |
paulb@572 | 59 | app_type = sys.argv[1] |
paulb@572 | 60 | app_location = sys.argv[2] |
paulb@572 | 61 | apache_site_dir = sys.argv[3] |
paulb@572 | 62 | site_name = sys.argv[4] |
paulb@572 | 63 | url_path = sys.argv[5] |
paulb@572 | 64 | if app_type not in ("mod_python", "CGI"): |
paulb@572 | 65 | print "Please specify either CGI or mod_python as the application type." |
paulb@572 | 66 | sys.exit(1) |
paulb@572 | 67 | |
paulb@572 | 68 | except IndexError: |
paulb@572 | 69 | print "config.py CGI|mod_python <app-location> <apache-site-dir> <site-name> <url-path>" |
paulb@572 | 70 | print |
paulb@572 | 71 | print "CGI configures a CGI application" |
paulb@572 | 72 | print "mod_python configures a mod_python application" |
paulb@572 | 73 | print |
paulb@572 | 74 | print "<app-location> is the full path to your application" |
paulb@572 | 75 | print "eg. %s/examples/CGI/SimpleHandler.py" % os.getcwd() |
paulb@572 | 76 | print |
paulb@572 | 77 | print "<apache-site-dir> is the directory where site configuration files are stored" |
paulb@572 | 78 | print "eg. /etc/apache2/sites-available" |
paulb@572 | 79 | print |
paulb@572 | 80 | print "<site-name> is the name of the site within Apache" |
paulb@572 | 81 | print "eg. simple" |
paulb@572 | 82 | print |
paulb@572 | 83 | print "<url-path> is the path at which your application will be published" |
paulb@572 | 84 | print "eg. /cgi/simple" |
paulb@572 | 85 | sys.exit(1) |
paulb@572 | 86 | |
paulb@572 | 87 | # Derived information. |
paulb@572 | 88 | |
paulb@572 | 89 | handler_dir, handler_name = os.path.split(app_location) |
paulb@572 | 90 | handler_name, extension = os.path.splitext(handler_name) |
paulb@572 | 91 | if handler_name == "" or extension != ".py": |
paulb@572 | 92 | print "Please specify the path to actual handler module file." |
paulb@572 | 93 | print "eg. %s/examples/ModPython/SimpleApp/SimpleHandler.py" % os.getcwd() |
paulb@572 | 94 | sys.exit(1) |
paulb@572 | 95 | |
paulb@572 | 96 | # Initialise an object representing an Apache server. |
paulb@572 | 97 | |
paulb@572 | 98 | apache_server = ApacheServer(apache_site_dir) |
paulb@572 | 99 | |
paulb@572 | 100 | # Set up the template and the sessions directory location. |
paulb@572 | 101 | |
paulb@572 | 102 | if app_type == "CGI": |
paulb@572 | 103 | template = cgi_template % (url_path, app_location) |
paulb@572 | 104 | sessions_dir = os.path.join(handler_dir, "WebStack-sessions") |
paulb@572 | 105 | |
paulb@572 | 106 | elif app_type == "mod_python": |
paulb@572 | 107 | template = mod_python_template % (url_path, handler_name, handler_dir) |
paulb@572 | 108 | server_root = apache_server.get_server_root_from_config() or apache_site_dir |
paulb@572 | 109 | sessions_dir = os.path.join(server_root, "WebStack-sessions") |
paulb@572 | 110 | |
paulb@572 | 111 | # Set up the site filename. |
paulb@572 | 112 | |
paulb@572 | 113 | site_filename = os.path.join(apache_site_dir, site_name) |
paulb@572 | 114 | |
paulb@572 | 115 | if os.path.exists(site_filename): |
paulb@572 | 116 | answer = raw_input("Overwrite existing site file? (Y|N) ") |
paulb@572 | 117 | if answer.upper() == "N": |
paulb@572 | 118 | print "Not overwriting." |
paulb@572 | 119 | sys.exit(1) |
paulb@572 | 120 | |
paulb@572 | 121 | # Write the site file. |
paulb@572 | 122 | |
paulb@572 | 123 | try: |
paulb@572 | 124 | f = open(site_filename, "wb") |
paulb@572 | 125 | f.write(template) |
paulb@572 | 126 | f.close() |
paulb@572 | 127 | except IOError: |
paulb@572 | 128 | print "Could not write the site file. Check your user privileges." |
paulb@572 | 129 | print |
paulb@572 | 130 | raise |
paulb@572 | 131 | |
paulb@572 | 132 | # Set up the sessions directory. |
paulb@572 | 133 | |
paulb@572 | 134 | if not os.path.exists(sessions_dir): |
paulb@572 | 135 | answer = raw_input("Create sessions directory at %s? (Y|N) " % sessions_dir) |
paulb@572 | 136 | if answer.upper() == "Y": |
paulb@572 | 137 | os.mkdir(sessions_dir) |
paulb@572 | 138 | |
paulb@572 | 139 | # Find the user who should own the sessions directory. |
paulb@572 | 140 | |
paulb@572 | 141 | if os.path.exists(sessions_dir): |
paulb@572 | 142 | try: |
paulb@572 | 143 | import pwd |
paulb@572 | 144 | username = apache_server.get_user_from_config() |
paulb@572 | 145 | if username is None: |
paulb@572 | 146 | print "Not able to determine the Web server user." |
paulb@572 | 147 | else: |
paulb@572 | 148 | print "Found", username, "as the Web server user." |
paulb@572 | 149 | try: |
paulb@572 | 150 | t = pwd.getpwnam(username) |
paulb@572 | 151 | uid, gid = t[2:4] |
paulb@572 | 152 | answer = raw_input("Set %s, %s as user, group on the sessions directory? (Y|N) " % (uid, gid)) |
paulb@572 | 153 | if answer.upper() == "Y": |
paulb@572 | 154 | os.chown(sessions_dir, uid, gid) |
paulb@572 | 155 | |
paulb@572 | 156 | except KeyError: |
paulb@572 | 157 | print "User not found in the password database." |
paulb@572 | 158 | except OSError: |
paulb@572 | 159 | print "Not able to change the ownership. Check your user privileges." |
paulb@572 | 160 | |
paulb@572 | 161 | except ImportError: |
paulb@572 | 162 | print "Not configuring the sessions directory ownership." |
paulb@572 | 163 | |
paulb@572 | 164 | # Check the permissions on the application. |
paulb@572 | 165 | |
paulb@572 | 166 | if app_type == "CGI": |
paulb@572 | 167 | try: |
paulb@572 | 168 | import stat |
paulb@572 | 169 | details = os.stat(app_location) |
paulb@572 | 170 | mode = stat.S_IMODE(details[stat.ST_MODE]) |
paulb@572 | 171 | |
paulb@572 | 172 | # Check for incorrect permissions. |
paulb@572 | 173 | |
paulb@572 | 174 | flags = stat.S_IRUSR|stat.S_IXUSR|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH |
paulb@572 | 175 | |
paulb@572 | 176 | # Set correct permissions. |
paulb@572 | 177 | |
paulb@572 | 178 | if mode & flags == flags: |
paulb@572 | 179 | print "Correct permissions found were", oct(mode), "for", app_location |
paulb@572 | 180 | else: |
paulb@572 | 181 | answer = raw_input("Change the permissions on %s? (Y|N) " % app_location) |
paulb@572 | 182 | if answer.upper() == "Y": |
paulb@572 | 183 | print "Setting mode", oct(flags), "on", app_location |
paulb@572 | 184 | os.chmod(app_location, flags) |
paulb@572 | 185 | |
paulb@572 | 186 | except ImportError: |
paulb@572 | 187 | print "Not changing the permissions on the application." |
paulb@572 | 188 | |
paulb@572 | 189 | print "--------" |
paulb@572 | 190 | print "Configuration completed." |
paulb@572 | 191 | print "You may need to run an administrative tool to add the new site '%s' to Apache." % site_name |
paulb@572 | 192 | print "eg. a2ensite" |
paulb@572 | 193 | print "You may also want to check any sys.path definitions in your application." |
paulb@572 | 194 | |
paulb@572 | 195 | # vim: tabstop=4 expandtab shiftwidth=4 |