Commits

Ian Bicking committed 8dfe4d6

Added PHP silver serve support

Comments (0)

Files changed (3)

silverlining/commands/php-devel-server.conf.tmpl

+LockFile {{tempdir}}/apache.lock
+
+PidFile {{apache_pid_file}}
+
+Timeout 600
+
+KeepAlive Off
+
+<IfModule mpm_prefork_module>
+    StartServers 1
+    MinSpareServers 1
+    MaxSpareServers 1
+    MaxClients 10
+    MaxRequestsPerChild 0
+</IfModule>
+
+<IfModule mpm_worker_module>
+    StartServers          1
+    MinSpareThreads      25
+    MaxSpareThreads      75 
+    ThreadLimit          64
+    ThreadsPerChild      25
+    MaxClients          150
+    MaxRequestsPerChild   0
+</IfModule>
+
+AccessFileName .htaccess
+
+<Files ~ "^\.ht">
+    Order allow,deny
+    Deny from all
+</Files>
+
+DefaultType text/plain
+
+HostnameLookups Off
+
+ErrorLog {{tempdir}}/error.log
+
+LogLevel info
+
+## FIXME: Figure out where to look for these?
+# Include module configuration:
+
+{{for inc in includes}}
+Include {{inc}}
+{{endfor}}
+
+## FIXME: How to load and conf mod_rewrite, etc?
+
+## FIXME: do we need this?
+#NameVirtualHost *:8080
+ServerName localhost
+Listen 8080
+
+<VirtualHost 127.0.0.1:8080>
+    ServerAdmin webmaster@localhost
+    <Directory />
+        Options FollowSymLinks
+        AllowOverride None
+    </Directory>
+    <Directory ./>
+        Options Indexes FollowSymLinks MultiViews
+        AllowOverride None
+        Order allow,deny
+        allow from all
+    </Directory>
+
+    <LocationMatch />
+         # Insert filter
+        SetOutputFilter DEFLATE
+
+        # Netscape 4.x has some problems...
+        BrowserMatch ^Mozilla/4 gzip-only-text/html
+
+        # Netscape 4.06-4.08 have some more problems
+        BrowserMatch ^Mozilla/4\.0[678] no-gzip
+
+        # MSIE masquerades as Netscape, but it is fine
+        BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
+        # Don't compress images
+        SetEnvIfNoCase Request_URI \
+        \.(?:gif|jpe?g|png)$ no-gzip dont-vary
+
+        # Make sure proxies don't deliver the wrong content
+        #Header append Vary User-Agent env=!dont-vary
+    </LocationMatch>
+
+    LogFormat "%{SILVER_FORWARDED}e %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %{HTTP_HOST}e \"%{SILVER_APP_NAME}e\" %D" wsgi_combined
+    CustomLog {{tempdir}}/access.log wsgi_combined
+
+
+## Python/WSGI setup:
+RewriteEngine on
+## Uncomment if you want to understand what is happening here:
+#RewriteLog /var/log/apache2/rewrite.log
+#RewriteLogLevel 5
+
+RewriteCond %{HTTP_HOST} ^([^:]*)
+RewriteRule . - [E=SILVER_HOSTNAME:%1]
+RewriteRule . - [E=SILVER_INSTANCE_DIR:{{silver_instance_dir}}]
+RewriteRule . - [E=SILVER_SECRET_FILE:{{silver_secret_file}}]
+RewriteRule . - [E=SILVER_ENV_VARS:{{silver_env_vars}}]
+RewriteRule . - [E=SILVER_FUNCS:{{silver_funcs}}]
+
+{{for prefix in path_prefixes}}
+RewriteCond ./{{prefix}}%{REQUEST_URI} -f
+RewriteRule (.*/)index.html $1 [L,R=permanent]
+RewriteCond ./{{prefix}}%{REQUEST_URI} -d
+RewriteCond %{REQUEST_URI} [^/]$
+RewriteCond ./{{prefix}}%{REQUEST_URI}/index.html -f
+RewriteRule (.*) $1/ [L,R=permanent]
+RewriteCond ./{{prefix}}%{REQUEST_URI} -f
+RewriteRule !\.php$ ./{{prefix}}%{REQUEST_URI} [L]
+{{endfor}}
+
+RewriteRule . {{mgr_scripts}}/master-runner.php [L]
+
+</VirtualHost>

silverlining/commands/serve.py

 import os
 import sys
 import subprocess
+import glob
+import tempfile
 from cmdutils import CommandError
+from tempita import Template
 from paste import httpserver
+import silversupport
+from silversupport.appconfig import AppConfig
+from silversupport.shell import run
 
 
 def command_serve(config):
     dir = os.path.abspath(config.args.dir)
-    if not os.path.exists(os.path.join(config.args.dir, 'app.ini')):
+    if not os.path.exists(os.path.join(dir, 'app.ini')):
         raise CommandError(
             "Could not find app.ini in %s" % config.args.dir)
+    appconfig = AppConfig(os.path.join(dir, 'app.ini'))
+    appconfig.check_service_setup(config.logger)
+    if appconfig.platform == 'python':
+        serve_python(config, appconfig)
+    elif appconfig.platform == 'php':
+        serve_php(config, appconfig)
+
+
+def serve_python(config, appconfig):
     if os.path.exists(os.path.join(dir, 'bin', 'python')):
         # We are in a virtualenv situation...
         cmd = [os.path.join(dir, 'bin', 'python'),
         print 'Terminating'
 
 
+def serve_php(config, appconfig):
+    apache_config_tmpl = Template.from_filename(
+        os.path.join(os.path.dirname(__file__), 'php-devel-server.conf.tmpl'))
+    path_prefixes = ['./static', appconfig.php_root]
+    if appconfig.writable_root_location:
+        path_prefixes.append(appconfig.writable_root_location
+                             + '/%{ENV:SILVER_HOSTNAME}')
+        path_prefixes.append(appconfig.writable_root_location)
+    tempdir = '/tmp'
+    includes = glob.glob('/etc/apache2/mods-enabled/*.load')
+    includes += glob.glob('/etc/apache2/mods-enabled/*.conf')
+    silver_secret_file = os.path.join(tempdir, 'secret.txt')
+    silver_env_vars = os.path.join(tempdir, 'silver-env-vars.php')
+    appconfig.write_php_env(silver_env_vars)
+    if not os.path.exists(silver_secret_file):
+        fp = open(silver_secret_file, 'wb')
+        fp.write('localsecret')
+        fp.close()
+    apache_config = apache_config_tmpl.substitute(
+        mgr_scripts=os.path.join(os.path.dirname(os.path.dirname(__file__)), 'mgr-scripts'),
+        path_prefixes=path_prefixes,
+        ## FIXME: better values:
+        tempdir=tempdir,
+        apache_pid_file='/tmp/apache.pid',
+        mods_dir='/etc/apache2/mods-enabled',
+        includes=includes,
+        silver_instance_dir=os.path.abspath(config.args.dir),
+        silver_secret_file=silver_secret_file,
+        silver_env_vars=silver_env_vars,
+        silver_funcs=os.path.join(os.path.dirname(silversupport.__file__), 'php', 'functions.php'),
+        )
+    temp_file = tempfile.mkstemp('.conf', 'silver-apache-')[1]
+    config.logger.info('Writing config to %s' % temp_file)
+    try:
+        fp = open(temp_file, 'w')
+        fp.write(apache_config)
+        fp.close()
+        exe_name = search_path(['apache2', 'apache', 'httpd'])
+        config.logger.notify('Serving on http://localhost:8080')
+        run([exe_name, '-f', temp_file,
+             '-d', config.args.dir, '-X'])
+    finally:
+        os.unlink(temp_file)
+    
+
 def _turn_sigterm_into_systemexit():
     """
     Attempts to turn a SIGTERM exception into a SystemExit exception.
     def handle_term(signo, frame):
         raise SystemExit
     signal.signal(signal.SIGTERM, handle_term)
+
+
+def search_path(exe_names):
+    ## FIXME: should I allow for some general environmental variable override here?
+    paths = os.environ['PATH'].split(os.path.pathsep)
+    for name in exe_names:
+        for path in paths:
+            if os.path.exists(os.path.join(path, name)):
+                return name
+    return exe_names[0]

silverlining/mgr-scripts/master-runner.php

 $silver_runner = $silver_app_config['production']['runner'];
 $silver_php_root = $silver_app_config['production']['php_root'];
 
-define('SILVER_SECRET', file_get_contents('/var/lib/silverlining/secret.txt'));
+if ($_SERVER['SILVER_SECRET_FILE']) {
+    define('SILVER_SECRET', file_get_contents($_SERVER['SILVER_SECRET_FILE']));
+} else {
+    define('SILVER_SECRET', file_get_contents('/var/lib/silverlining/secret.txt'));
+}
 
-require_once "/usr/local/share/silverlining/lib/silversupport/php/functions.php";
-include "{$silver_base}/silver-env-variables.php";
+if ($_SERVER['SILVER_FUNCS']) {
+    require_once $_SERVER['SILVER_FUNCS'];
+} else {
+    require_once "/usr/local/share/silverlining/lib/silversupport/php/functions.php";
+}
+if ($_SERVER['SILVER_ENV_VARS']) {
+    include $_SERVER['SILVER_ENV_VARS'];
+} else {
+    include "{$silver_base}/silver-env-variables.php";
+}
 include "{$silver_base}/{$silver_runner}";
 
 ?>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.