Show More
@@ -0,0 +1,85 b'' | |||
|
1 | import os | |
|
2 | import sys | |
|
3 | from paste.script.appinstall import AbstractInstallCommand | |
|
4 | from paste.script.command import BadCommand | |
|
5 | ||
|
6 | # Add location of top level folder to sys.path | |
|
7 | from os.path import dirname as dn | |
|
8 | rc_path = dn(dn(dn(os.path.realpath(__file__)))) | |
|
9 | sys.path.append(rc_path) | |
|
10 | ||
|
11 | class Command(AbstractInstallCommand): | |
|
12 | default_verbosity = 1 | |
|
13 | max_args = 1 | |
|
14 | min_args = 1 | |
|
15 | summary = 'Setup IIS given a config file' | |
|
16 | usage = 'CONFIG_FILE' | |
|
17 | ||
|
18 | description = ''' | |
|
19 | Script for installing into IIS using isapi-wsgi. | |
|
20 | ''' | |
|
21 | parser = AbstractInstallCommand.standard_parser( | |
|
22 | simulate=True, quiet=True, interactive=True) | |
|
23 | parser.add_option('--virtualdir', | |
|
24 | action='store', | |
|
25 | dest='virtualdir', | |
|
26 | default='/', | |
|
27 | help='The virtual folder to install into on IIS') | |
|
28 | ||
|
29 | def command(self): | |
|
30 | config_spec = self.args[0] | |
|
31 | if not config_spec.startswith('config:'): | |
|
32 | config_spec = 'config:' + config_spec | |
|
33 | config_file = config_spec[len('config:'):].split('#', 1)[0] | |
|
34 | config_file = os.path.join(os.getcwd(), config_file) | |
|
35 | try: | |
|
36 | import isapi_wsgi | |
|
37 | except ImportError: | |
|
38 | raise BadCommand('missing requirement: isapi-wsgi not installed') | |
|
39 | ||
|
40 | file = '''import sys | |
|
41 | ||
|
42 | if hasattr(sys, "isapidllhandle"): | |
|
43 | import win32traceutil | |
|
44 | ||
|
45 | import isapi_wsgi | |
|
46 | import os | |
|
47 | ||
|
48 | def __ExtensionFactory__(): | |
|
49 | from paste.deploy import loadapp | |
|
50 | from paste.script.util.logging_config import fileConfig | |
|
51 | fileConfig('%(inifile)s') | |
|
52 | application = loadapp('config:%(inifile)s') | |
|
53 | ||
|
54 | def app(environ, start_response): | |
|
55 | user = environ.get('REMOTE_USER', None) | |
|
56 | if user is not None: | |
|
57 | os.environ['REMOTE_USER'] = user | |
|
58 | return application(environ, start_response) | |
|
59 | ||
|
60 | return isapi_wsgi.ISAPIThreadPoolHandler(app) | |
|
61 | ||
|
62 | if __name__=='__main__': | |
|
63 | from isapi.install import * | |
|
64 | params = ISAPIParameters() | |
|
65 | sm = [ScriptMapParams(Extension="*", Flags=0)] | |
|
66 | vd = VirtualDirParameters(Name="%(virtualdir)s", | |
|
67 | Description = "Kallithea", | |
|
68 | ScriptMaps = sm, | |
|
69 | ScriptMapUpdate = "replace") | |
|
70 | params.VirtualDirs = [vd] | |
|
71 | HandleCommandLine(params) | |
|
72 | ''' | |
|
73 | ||
|
74 | outdata = file % { | |
|
75 | 'inifile': config_file.replace('\\', '\\\\'), | |
|
76 | 'virtualdir': self.options.virtualdir | |
|
77 | } | |
|
78 | ||
|
79 | dispatchfile = os.path.join(os.getcwd(), 'dispatch.py') | |
|
80 | self.ensure_file(dispatchfile, outdata, False) | |
|
81 | print 'generating', dispatchfile | |
|
82 | ||
|
83 | print ('run \'python "%s" install\' with administrative privileges ' | |
|
84 | 'to generate the _dispatch.dll file and install it into the ' | |
|
85 | 'default web site') % (dispatchfile,) |
@@ -44,50 +44,24 b' to run on the website and consequently, ' | |||
|
44 | 44 | ISAPI Handler |
|
45 | 45 | ............. |
|
46 | 46 | |
|
47 |
The ISAPI handler n |
|
|
48 | Kallithea installation is in ``c:\inetpub\kallithea``, we would have a file in | |
|
49 | the same directory called, e.g. ``dispatch.py`` with the following contents:: | |
|
50 | ||
|
51 | import sys | |
|
47 | The ISAPI handler can be generated using:: | |
|
52 | 48 |
|
|
53 | if hasattr(sys, "isapidllhandle"): | |
|
54 | import win32traceutil | |
|
55 | ||
|
56 | import isapi_wsgi | |
|
57 | ||
|
58 | def __ExtensionFactory__(): | |
|
59 | from paste.deploy import loadapp | |
|
60 | from paste.script.util.logging_config import fileConfig | |
|
61 | fileConfig('c:\\inetpub\\kallithea\\production.ini') | |
|
62 | application = loadapp('config:c:\\inetpub\\kallithea\\production.ini') | |
|
49 | paster install-iis my.ini --root=/ | |
|
63 | 50 | |
|
64 | def app(environ, start_response): | |
|
65 | user = environ.get('REMOTE_USER', None) | |
|
66 | if user is not None: | |
|
67 | os.environ['REMOTE_USER'] = user | |
|
68 | return application(environ, start_response) | |
|
69 | ||
|
70 | return isapi_wsgi.ISAPIThreadPoolHandler(app) | |
|
51 | This will generate a ``dispatch.py`` file in the current directory that contains | |
|
52 | the necessary components to finalize an installation into IIS. Once this file | |
|
53 | has been generated, it is necessary to run the following command due to the way | |
|
54 | that ISAPI-WSGI is made:: | |
|
71 | 55 | |
|
72 | if __name__=='__main__': | |
|
73 | from isapi.install import * | |
|
74 | params = ISAPIParameters() | |
|
75 | sm = [ScriptMapParams(Extension="*", Flags=0)] | |
|
76 | vd = VirtualDirParameters(Name="/", | |
|
77 | Description = "ISAPI-WSGI Echo Test", | |
|
78 | ScriptMaps = sm, | |
|
79 | ScriptMapUpdate = "replace") | |
|
80 | params.VirtualDirs = [vd] | |
|
81 | HandleCommandLine(params) | |
|
56 | python dispatch.py install | |
|
82 | 57 | |
|
83 | This script has two parts: First, when run directly using Python, it will | |
|
84 | install a script map ISAPI handler into the root application of the default | |
|
85 | website, and secondly it will be called from the ISAPI handler when invoked | |
|
86 | from the website. | |
|
58 | This accomplishes two things: generating an ISAPI compliant DLL file, | |
|
59 | ``_dispatch.dll``, and installing a script map handler into IIS for the | |
|
60 | ``--root`` specified above pointing to ``_dispatch.dll``. | |
|
87 | 61 | |
|
88 | 62 | The ISAPI handler is registered to all file extensions, so it will automatically |
|
89 |
be the one handling all requests to the |
|
|
90 | ISAPI handler, it will start a thread pool managed wrapper around the paster | |
|
63 | be the one handling all requests to the specified root. When the website starts | |
|
64 | the ISAPI handler, it will start a thread pool managed wrapper around the paster | |
|
91 | 65 | middleware WSGI handler that Kallithea runs within and each HTTP request to the |
|
92 | 66 | site will be processed through this logic henceforth. |
|
93 | 67 |
@@ -180,5 +180,6 b' setup(' | |||
|
180 | 180 | make-index=kallithea.lib.paster_commands.make_index:Command |
|
181 | 181 | upgrade-db=kallithea.lib.dbmigrate:UpgradeDb |
|
182 | 182 | celeryd=kallithea.lib.celerypylons.commands:CeleryDaemonCommand |
|
183 | install-iis=kallithea.lib.paster_commands.install_iis:Command | |
|
183 | 184 | """, |
|
184 | 185 | ) |
General Comments 0
You need to be logged in to leave comments.
Login now