Commit e3a11eaa authored by Kirill Smelkov's avatar Kirill Smelkov

helloworld: Move helloweb program to component/helloweb

This

- better illustrates what components do (provide building recipes for
  programs) and what software do (gather components and provide recipes
  for instances).

- illustrates how to build the software properly - usually we build
  eggs or scripts with zc.recipe.egg:* , not generate python programs via
  jinja2 templating. Because when installing via egg, it is possible to
  import other installed eggs relatively straghtforward, and for jinja2
  way it is hard to do.

The helloweb program itself is moved into newly introduced helloweb.git
repository and, as almost all other software, becomes separate from
slapos.git .

/cc @jerome
parent 4a4e3e32
# helloweb - programs to say hello to the Web in various languages
[buildout]
extends =
../git/buildout.cfg
parts =
helloweb
# repository with examples
[helloweb-repository]
recipe = slapos.recipe.build:gitclone
git-executable = ${git:location}/bin/git
repository = https://lab.nexedi.com/nexedi/helloweb.git
revision = 88d517131e75929f79a4d36de4124dab4521614a
location = ${buildout:parts-directory}/helloweb
[helloweb-egg]
recipe = zc.recipe.egg:develop
egg = helloweb
setup = ${helloweb-repository:location}/python/
[helloweb]
recipe = zc.recipe.egg:scripts
eggs = ${helloweb-egg:egg}
scripts = helloweb
#!{{ python_executable }}
"""Simple web-server that says "Hello World" for every path
helloweb [--logfile <logfile>] <bind-ip> <bind-port> ...
"""
import sys
import time
import argparse
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from socket import AF_INET6
class WebHello(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200) # ok
self.send_header("Content-type", "text/plain")
self.end_headers()
print >>self.wfile, \
"Hello %s at `%s` ; %s" % (
' '.join(self.server.webhello_argv) or 'world',
self.path, time.asctime())
class HTTPServerV6(HTTPServer):
address_family = AF_INET6
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--logfile', dest='logfile')
parser.add_argument('bind_ip')
parser.add_argument('bind_port', type=int)
parser.add_argument('argv_extra', metavar='...', nargs=argparse.REMAINDER)
args = parser.parse_args()
# HTTPServer logs to sys.stderr - override it if we have --logfile
if args.logfile:
f = open(args.logfile, 'a', buffering=1)
sys.stderr = f
print >>sys.stderr, '* %s helloweb starting at %s' % (
time.asctime(), (args.bind_ip, args.bind_port))
# TODO autodetect ipv6/ipv4
httpd = HTTPServerV6( (args.bind_ip, args.bind_port), WebHello)
httpd.webhello_argv = args.argv_extra
httpd.serve_forever()
if __name__ == '__main__':
main()
...@@ -81,7 +81,7 @@ logfile = $${directory:log}/helloweb.log ...@@ -81,7 +81,7 @@ logfile = $${directory:log}/helloweb.log
# This recipe will try to "exec" the command-line after separating parameters. # This recipe will try to "exec" the command-line after separating parameters.
recipe = slapos.cookbook:wrapper recipe = slapos.cookbook:wrapper
command-line = command-line =
${helloweb-bin:rendered} --logfile $${helloweb:logfile} ${buildout:bin-directory}/helloweb --logfile $${helloweb:logfile}
$${:ipv6} $${:port} $${instance-parameter:configuration.name} $${:ipv6} $${:port} $${instance-parameter:configuration.name}
# Put this shell script in the "etc/service" directory. Each executable of this # Put this shell script in the "etc/service" directory. Each executable of this
# repository will be started and monitored by supervisord. If a service # repository will be started and monitored by supervisord. If a service
......
...@@ -6,10 +6,10 @@ extends = ...@@ -6,10 +6,10 @@ extends =
../../stack/slapos.cfg ../../stack/slapos.cfg
# Extend here component profiles, like openssl, apache, mariadb, curl... # Extend here component profiles, like openssl, apache, mariadb, curl...
# Or/and extend a stack (lamp, tomcat) that does most of the work for you # Or/and extend a stack (lamp, tomcat) that does most of the work for you
# In this example we don't need anything more than python which is provided by # In this example we extend from helloweb component.
# above stack/slapos.cfg
# ../../component/component1/buildout.cfg # ../../component/component1/buildout.cfg
# ../../component/component2/buildout.cfg # ../../component/component2/buildout.cfg
../../component/helloweb/buildout.cfg
parts = parts =
# Call installation of slapos.cookbook egg defined in stack/slapos.cfg (needed # Call installation of slapos.cookbook egg defined in stack/slapos.cfg (needed
...@@ -19,8 +19,8 @@ parts = ...@@ -19,8 +19,8 @@ parts =
# instance # instance
instance-profile instance-profile
# "build" python program (install + correct shebang for our python) # build helloweb program
helloweb-bin helloweb
# Download instance.cfg.in (buildout profile used to deployment of instance), # Download instance.cfg.in (buildout profile used to deployment of instance),
...@@ -31,23 +31,5 @@ recipe = slapos.recipe.template ...@@ -31,23 +31,5 @@ recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg.in url = ${:_profile_base_location_}/instance.cfg.in
output = ${buildout:directory}/instance.cfg output = ${buildout:directory}/instance.cfg
# MD5 checksum can be skipped for development (easier to develop), but must be filled for production # MD5 checksum can be skipped for development (easier to develop), but must be filled for production
md5sum = 1861b47bcc4dc61751857193303c8bef md5sum = 38243467b23a9abfa728bd4d30ab51ad
mode = 0644 mode = 0644
# install helloweb with correct python_executable
[helloweb-bin]
recipe = slapos.recipe.template:jinja2
filename = helloweb
md5sum = 2cfa80eba8cadea3e9cad64db2e3f536
template = ${:_profile_base_location_}/${:filename}.in
rendered = ${buildout:bin-directory}/${:filename}
mode = 0755
# XXX python_executable should be ${${buildout:python}:executable}
# but buildout cannot support such indirection.
#
# in real-cases, python software is usually installed with zc.recipe.egg
# which cares about correctly specifiing python interpreter for
# entry-points automatically.
context =
raw python_executable ${buildout:executable}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment