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