Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 3 additions & 121 deletions .run-httpd.py
Original file line number Diff line number Diff line change
@@ -1,137 +1,19 @@
#!/usr/bin/env python
from tempfile import mkdtemp
from os.path import join, exists
from subprocess import Popen, PIPE, check_output
from argparse import ArgumentParser
from shutil import rmtree
from time import sleep
from re import compile
from os import mkdir

from httpd import run_apache_with_jekyll

parser = ArgumentParser(description='Serve Jekyll site')

parser.add_argument('--watch', dest='watch', action='store_true',
help='Watch for changes and rebuild.')

config = '''
LoadModule rewrite_module {ModulesPath}/mod_rewrite.so
LoadModule alias_module {ModulesPath}/mod_alias.so
LoadModule dir_module {ModulesPath}/mod_dir.so
LoadModule mime_module {ModulesPath}/mod_mime.so

<IfDefine Unixd>
LoadModule unixd_module {ModulesPath}/mod_unixd.so
</IfDefine>

<IfDefine MpmEvent>
LoadModule mpm_event_module {ModulesPath}/mod_mpm_event.so
</IfDefine>

<IfDefine Version2.2>
LoadModule log_config_module {ModulesPath}/mod_log_config.so
LockFile "{ServerRoot}/accept.lock"
</IfDefine>

<IfDefine Version2.4>
LoadModule authz_core_module {ModulesPath}/mod_authz_core.so
Mutex file:{ServerRoot}
</IfDefine>

Listen 0.0.0.0:{Port}
PidFile "{ServerRoot}/httpd.pid"
DocumentRoot "{DocumentRoot}"
TypesConfig {MimeTypes}

<Directory "{DocumentRoot}">
Options +FollowSymLinks
AllowOverride Options FileInfo Indexes
</Directory>
'''

def build_site(destination, watch):
'''
'''
command = 'jekyll', 'build', '-d', destination

if watch:
command += ('--watch', )

Popen(command).wait()
print 'Built to', destination

def write_config(doc_root, root, port):
''' Look for Apache modules, write a configuration file.

Return module directory.
'''
mod_paths = '/usr/lib/apache2/modules', '/usr/libexec/apache2'
mime_paths = '/etc/apache2/mime.types', '/etc/mime.types'

mod_path = filter(exists, mod_paths)[0]
mime_path = filter(exists, mime_paths)[0]

vars = dict(DocumentRoot=doc_root, ModulesPath=mod_path,
Port=port, ServerRoot=root, MimeTypes=mime_path)

with open(join(root, 'httpd.conf'), 'w') as file:
file.write(config.format(**vars))

if not exists(join(root, 'httpd.conf')):
raise RuntimeError('Did not make httpd.conf')

return mod_path

def apache_version(httpd_path):
''' Return major, minor version tuple.
'''
pattern = compile(r'^Server version: Apache/(\d+)\.(\d+)\.(\d+)\b')
match = pattern.match(check_output((httpd_path, '-v')))
major, minor, patch = [int(match.group(i)) for i in (1, 2, 3)]

return major, minor

def run_apache(root, port, watch):
''' Look for Apache executable and start it up.
'''
try:
doc_root = join(root, '_site')
mkdir(doc_root)
mkdir(join(root, 'logs'))

mod_path = write_config(doc_root, root, port)
httpd_paths = '/usr/sbin/httpd', '/usr/sbin/apache2'
httpd_path = filter(exists, httpd_paths)[0]

version_param = '-DVersion{}.{}'.format(*apache_version(httpd_path))

httpd_cmd = (httpd_path, '-d', root, '-f', 'httpd.conf',
'-DFOREGROUND', '-DNO_DETACH', version_param)

if exists(join(mod_path, 'mod_unixd.so')):
httpd_cmd += ('-DUnixd', )

if exists(join(mod_path, 'mod_mpm_event.so')):
httpd_cmd += ('-DMpmEvent', )

stderr = open(join(root, 'stderr'), 'w')
stdout = open(join(root, 'stdout'), 'w')

try:
httpd = Popen(httpd_cmd, stderr=stderr, stdout=stdout)
print 'Running at http://127.0.0.1:{}'.format(port)
build_site(doc_root, watch)
sleep(7 * 86400)
finally:
httpd.kill()

except KeyboardInterrupt:
rmtree(root)

def main():
'''
'''
args = parser.parse_args()
run_apache(mkdtemp(prefix='codeforamerica.org-'), 4000, args.watch)
run_apache_with_jekyll(mkdtemp(prefix='codeforamerica.org-'), 4000, args.watch)

if __name__ == '__main__':
exit(main())
3 changes: 0 additions & 3 deletions .run-tests.sh

This file was deleted.

37 changes: 6 additions & 31 deletions .test-httpd.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env python
from tempfile import mkdtemp
from os.path import join, abspath, dirname, exists
from os.path import join, abspath, dirname
from urlparse import urljoin, urlparse
from httplib import HTTPConnection
from subprocess import Popen, PIPE
from random import randrange
from shutil import rmtree
from time import sleep

from httpd import run_apache_forever, build_site

import unittest

config = '''
Expand Down Expand Up @@ -38,36 +39,9 @@ def setUp(self):
'''
self.root = mkdtemp()
self.port = randrange(0x1000, 0x10000)
doc_root = join(dirname(abspath(__file__)), '_site')

#
# Look for Apache modules, write a configuration file.
#
for mod_path in ('/usr/lib/apache2/modules', '/usr/libexec/apache2'):
if not exists(join(mod_path, 'mod_dir.so')):
continue

doc_root = join(dirname(abspath(__file__)), '_site')
log_config_so_path = join(mod_path, 'mod_log_config.so')
log_config_prefix = '' if exists(log_config_so_path) else '#'
vars = dict(DocumentRoot=doc_root, ModulesPath=mod_path,
Port=self.port, MLCP=log_config_prefix)

with open(join(self.root, 'httpd.conf'), 'w') as file:
file.write(config.format(**vars))

if not exists(join(self.root, 'httpd.conf')):
raise RuntimeError('Did not make httpd.conf')

#
# Look for Apache executable and start it up.
#
for httpd_path in ('/usr/sbin/httpd', '/usr/sbin/apache2'):
if not exists(httpd_path):
continue

httpd_cmd = (httpd_path, '-d', self.root, '-f', 'httpd.conf', '-X')

self.httpd = Popen(httpd_cmd, stderr=PIPE, stdout=PIPE)
self.httpd = run_apache_forever(doc_root, self.root, self.port, False)
sleep(.5)

def tearDown(self):
Expand Down Expand Up @@ -229,4 +203,5 @@ def test_redirects(self):
assert end_path == url_path, '{0} instead of {1} from {2}'.format(url_path, end_path, start_path)

if __name__ == '__main__':
build_site(join(dirname(abspath(__file__)), '_site'), False)
unittest.main()
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ language: ruby
before_install:
- travis_retry gem install jekyll --no-ri --no-rdoc
- sudo apt-get install -y apache2
script: ./.run-tests.sh
script: ./.test-httpd.py
branches:
only:
- master
Expand Down
158 changes: 158 additions & 0 deletions httpd/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
from os.path import join, exists
from subprocess import Popen, PIPE, check_output
from shutil import rmtree
from time import sleep
from re import compile
from os import mkdir

config = '''
LoadModule rewrite_module {ModulesPath}/mod_rewrite.so
LoadModule alias_module {ModulesPath}/mod_alias.so
LoadModule dir_module {ModulesPath}/mod_dir.so
LoadModule mime_module {ModulesPath}/mod_mime.so

<IfDefine Unixd>
LoadModule unixd_module {ModulesPath}/mod_unixd.so
</IfDefine>

<IfDefine MpmEvent>
LoadModule mpm_event_module {ModulesPath}/mod_mpm_event.so
</IfDefine>

<IfDefine Version2.2>
LoadModule log_config_module {ModulesPath}/mod_log_config.so
LockFile "{ServerRoot}/accept.lock"
</IfDefine>

<IfDefine Version2.4>
LoadModule authz_core_module {ModulesPath}/mod_authz_core.so
Mutex file:{ServerRoot}
</IfDefine>

Listen 0.0.0.0:{Port}
PidFile "{ServerRoot}/httpd.pid"
DocumentRoot "{DocumentRoot}"
TypesConfig {MimeTypes}

<Directory "/">
Options +FollowSymLinks
AllowOverride Options FileInfo Indexes
</Directory>
'''

def build_site(destination, watch):
'''
'''
command = 'jekyll', 'build', '-d', destination

if watch:
command += ('--watch', )

Popen(command).wait()
print 'Built to', destination

def write_config(doc_root, root, port):
''' Look for Apache modules, write a configuration file.

Return module directory.
'''
mod_paths = '/usr/lib/apache2/modules', '/usr/libexec/apache2'
mime_paths = '/etc/apache2/mime.types', '/etc/mime.types'

mod_path = filter(exists, mod_paths)[0]
mime_path = filter(exists, mime_paths)[0]

vars = dict(DocumentRoot=doc_root, ModulesPath=mod_path,
Port=port, ServerRoot=root, MimeTypes=mime_path)

with open(join(root, 'httpd.conf'), 'w') as file:
file.write(config.format(**vars))

if not exists(join(root, 'httpd.conf')):
raise RuntimeError('Did not make httpd.conf')

return mod_path

def apache_version(httpd_path):
''' Return major, minor version tuple.
'''
pattern = compile(r'^Server version: Apache/(\d+)\.(\d+)\.(\d+)\b')
match = pattern.match(check_output((httpd_path, '-v')))
major, minor, patch = [int(match.group(i)) for i in (1, 2, 3)]

return major, minor

def run_apache_with_jekyll(root, port, watch):
''' Look for Apache executable and start it up.

When the user cancels or kills the process, stop Apache.
'''
try:
doc_root = join(root, '_site')
mkdir(doc_root)
mkdir(join(root, 'logs'))

mod_path = write_config(doc_root, root, port)
httpd_paths = '/usr/sbin/httpd', '/usr/sbin/apache2'
httpd_path = filter(exists, httpd_paths)[0]

version_param = '-DVersion{}.{}'.format(*apache_version(httpd_path))

httpd_cmd = (httpd_path, '-d', root, '-f', 'httpd.conf',
'-DFOREGROUND', '-DNO_DETACH', version_param)

if exists(join(mod_path, 'mod_unixd.so')):
httpd_cmd += ('-DUnixd', )

if exists(join(mod_path, 'mod_mpm_event.so')):
httpd_cmd += ('-DMpmEvent', )

stderr = open(join(root, 'stderr'), 'w')
stdout = open(join(root, 'stdout'), 'w')

try:
httpd = Popen(httpd_cmd, stderr=stderr, stdout=stdout)
print 'Running at http://127.0.0.1:{}'.format(port)
build_site(doc_root, watch)
sleep(7 * 86400)
finally:
httpd.kill()

except KeyboardInterrupt:
rmtree(root)

def run_apache_forever(doc_root, root, port, watch):
''' Look for Apache executable and start it up.

Return an instance of subprocess.Process.

Assumes that jekyll build has already created root/_site.
'''
try:
mkdir(join(root, 'logs'))

mod_path = write_config(doc_root, root, port)
httpd_paths = '/usr/sbin/httpd', '/usr/sbin/apache2'
httpd_path = filter(exists, httpd_paths)[0]

version_param = '-DVersion{}.{}'.format(*apache_version(httpd_path))

httpd_cmd = (httpd_path, '-d', root, '-f', 'httpd.conf',
'-DFOREGROUND', '-DNO_DETACH', version_param)

if exists(join(mod_path, 'mod_unixd.so')):
httpd_cmd += ('-DUnixd', )

if exists(join(mod_path, 'mod_mpm_event.so')):
httpd_cmd += ('-DMpmEvent', )

stderr = open(join(root, 'stderr'), 'w')
stdout = open(join(root, 'stdout'), 'w')

httpd = Popen(httpd_cmd, stderr=stderr, stdout=stdout)
print 'Running at http://127.0.0.1:{} from {}'.format(port, root)

return httpd

except KeyboardInterrupt:
rmtree(root)