############################# # # Deploy hello-world instance # ############################# [buildout] parts = directory publish-connection-parameter # Define egg directories to be the one from Software Release # (/opt/slapgrid/...) # Always the same. eggs-directory = {{ buildout['eggs-directory'] }} develop-eggs-directory = {{ buildout['develop-eggs-directory'] }} offline = true extends = {{ template_monitor }} [instance-parameter] # Fetch arbitrary parameters defined by the user in SlapOS Master for his instance. # We use the slapconfiguration recipe with a few parameters (partition id, # computer id, certificate, etc). # It will then authenticate to SlapOS Master and fetch the instance parameters. # The parameters are accessible from ${instance-parameter:configuration.name-of-parameter} # Always the same. Just copy/paste. # See docstring of slapos.cookbook:slapconfiguration for more information. recipe = slapos.cookbook:slapconfiguration computer = ${slap_connection:computer_id} partition = ${slap_connection:partition_id} url = ${slap_connection:server_url} key = ${slap_connection:key_file} cert = ${slap_connection:cert_file} # Define default parameter(s) that will be used later, in case user didn't # specify it. # All possible parameters should have a default. # In our use case, we are expecting from the user to specify one (optional) parameter: "name". We put the default value here if he doesn't specify it, so that it doesn't crash. configuration.name = John Doe # If our use case requires that the user can specify a mail address so that his instance can mail to him (for example), we can do: # configuration.mail-address = # If the user doesn't specify it, it won't break and the recipe can handle it (i.e don't send any mail for example). # Create all needed directories, depending on your needs [directory] recipe = slapos.cookbook:mkdirectory home = ${buildout:directory} etc = ${:home}/etc var = ${:home}/var # Executables put here will be started but not monitored (for startup scripts) script = ${:etc}/run/ # Executables put here will be started and monitored (for daemons) service = ${:etc}/service # Path of the log directory used by our service (see [helloweb]) log = ${:var}/log # Create a simple web server that says "hello <configuration.name>" to the web. [helloweb] # helloworld service is listening on: # - global IPv6 address, and # - fixed port # # NOTE because every computer partition is allocated its own global IPv6 # address, it is ok to fix the port - different hello-world instances will have # different IPv6 addresses and they all will be accessible at the same time. ipv6 = ${instance-parameter:ipv6-random} # full URL - for convenience url = http://[${:ipv6}]:${:port} # the service will log here logfile = ${directory:log}/helloweb-${:kind}.log # Actual script that starts the service: # This recipe will try to "exec" the command-line after separating parameters. recipe = slapos.cookbook:wrapper command-line = {{ buildout['bin-directory'] }}/helloweb-${:kind} --logfile ${:logfile} ${:ipv6} ${:port} ${instance-parameter:configuration.name} # Put this shell script in the "etc/service" directory. Each executable of this # repository will be started and monitored by supervisord. If a service # exits/crashes, it will trigger a "bang" and cause a re-run of the instance. wrapper-path = ${directory:service}/helloweb-${:kind} # promise, that checks that helloweb service is alive [helloweb-promise] <= monitor-promise-base module = check_port_listening name = helloweb-${:kind}.py {# macro to instantiate service of `kind` to listen on `port` #} {% set service_list = [] %} {% macro hellowebsrv(kind, port) %} {% do service_list.append(kind) %} [helloweb-{{ kind }}] <= helloweb kind = {{ kind }} port = {{ port }} [helloweb-{{ kind }}-promise] <= helloweb-promise kind = {{ kind }} config-hostname= ${helloweb-{{ kind }}:ipv6} config-port = {{ port }} {% endmacro %} # services instantiation {{ hellowebsrv('python', 7777) }} {{ hellowebsrv('ruby', 7778) }} {{ hellowebsrv('go', 7779) }} # register all services/promises to buildout parts [buildout] parts += {%- for kind in service_list %} helloweb-{{ kind }} helloweb-{{ kind }}-promise {%- endfor %} # Publish all the parameters needed for the user to connect to the instance. # It can be anything: URL(s), password(s), or arbitrary parameters. # Here we'll just echo back the entered name as instance parameter [publish-connection-parameter] recipe = slapos.cookbook:publish name = Hello ${instance-parameter:configuration.name}! {%- for kind in service_list %} url.{{ kind }} = ${helloweb-{{ kind }}:url} {%- endfor %}