software/theia: Add switch-softwaretype
This defers the rendering of `instance-theia.cfg.in` to the instance creation time instead of the software installation time, which will allow buildout sections to be added based on the instance parameters. See merge request !981
Showing
[buildout] | ||
extends = | ||
${monitor-template:rendered} | ||
theia-environment-parts = | ||
tasks.json | ||
slapos-repository | ||
runner-link | ||
settings.json | ||
request-script-template | ||
theia-parts = | ||
frontend-reload | ||
promises | ||
parts = | ||
monitor-base | ||
$${:theia-parts} | ||
$${:theia-environment-parts} | ||
publish-connection-parameter | ||
eggs-directory = ${buildout:eggs-directory} | ||
develop-eggs-directory = ${buildout:develop-eggs-directory} | ||
offline = true | ||
[instance-parameter] | ||
{% for k, v in slapconfiguration_section.items() -%} | ||
{{ k }} = {{ v }} | ||
{% endfor -%} | ||
[publish-connection-parameter] | ||
<= monitor-publish | ||
recipe = slapos.cookbook:publish | ||
url = $${apache-frontend:connection-secure_access} | ||
username = $${frontend-instance-password:username} | ||
password = $${frontend-instance-password:passwd} | ||
backend-url = $${frontend-instance:url} | ||
[directory] | ||
recipe = slapos.cookbook:mkdirectory | ||
etc = $${buildout:directory}/etc | ||
var = $${buildout:directory}/var | ||
srv = $${buildout:directory}/srv | ||
bin = $${buildout:directory}/bin | ||
tmp = $${buildout:directory}/tmp | ||
dot-theia = $${buildout:directory}/.theia/ | ||
pidfiles = $${:var}/run | ||
services = $${:etc}/service | ||
runner = $${:srv}/runner | ||
project = $${:srv}/project | ||
frontend-static = $${:srv}/frontend-static | ||
frontend-static-public = $${:frontend-static}/public | ||
frontend-static-css = $${:frontend-static}/css | ||
bash-completions = $${buildout:directory}/.local/share/bash-completion/completions/ | ||
fish-completions = $${buildout:directory}/.config/fish/completions/ | ||
# Promises | ||
# -------- | ||
[promises] | ||
recipe = | ||
instance-promises = | ||
$${theia-listen-promise:name} | ||
$${frontend-listen-promise:name} | ||
$${apache-frontend-url-available-promise:name} | ||
$${slapos-standalone-listen-promise:name} | ||
$${slapos-autorun-promise:name} | ||
[theia-listen-promise] | ||
<= monitor-promise-base | ||
module = check_port_listening | ||
name = $${:_buildout_section_name_}.py | ||
config-hostname = $${theia-instance:ip} | ||
config-port = $${theia-instance:port} | ||
[frontend-listen-promise] | ||
<= monitor-promise-base | ||
module = check_port_listening | ||
name = $${:_buildout_section_name_}.py | ||
config-hostname = $${frontend-instance:ip} | ||
config-port = $${frontend-instance:port} | ||
[apache-frontend-url-available-promise] | ||
<= monitor-promise-base | ||
module = check_url_available | ||
name = $${:_buildout_section_name_}.py | ||
config-url = $${apache-frontend:connection-secure_access} | ||
config-check-secure = 1 | ||
[slapos-standalone-listen-promise] | ||
<= monitor-promise-base | ||
module = check_port_listening | ||
# XXX promise plugins can not contain "slapos" in their names | ||
name = standalone-listen-promise.py | ||
config-hostname = $${slapos-standalone-instance:hostname} | ||
config-port = $${slapos-standalone-instance:port} | ||
[slapos-autorun-promise] | ||
<= monitor-promise-base | ||
module = check_service_state | ||
# XXX promise plugins can not contain "slapos" in their names | ||
name = autorun-state-promise.py | ||
config-service = $${slapos-autorun:service-name} | ||
config-expect = $${slapos-autorun:autorun} | ||
# Remote Apache Frontend | ||
# ---------------------- | ||
[apache-frontend] | ||
<= slap-connection | ||
recipe = slapos.cookbook:requestoptional | ||
name = Theia Frontend | ||
# XXX We have hardcoded SR URL here. | ||
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg | ||
slave = true | ||
config-url = $${frontend-instance:url} | ||
config-https-only = true | ||
config-type = websocket | ||
config-websocket-path-list = /services /file-upload | ||
return = domain secure_access | ||
# Local Caddy Frontend | ||
# -------------------- | ||
[frontend-instance-password] | ||
recipe = slapos.cookbook:generate.password | ||
username = admin | ||
bytes = 12 | ||
[frontend-instance-port] | ||
recipe = slapos.cookbook:free_port | ||
minimum = 3000 | ||
maximum = 3100 | ||
ip = $${instance-parameter:ipv6-random} | ||
[frontend-instance-certificate] | ||
recipe = plone.recipe.command | ||
command = | ||
if [ ! -e $${:key-file} ] | ||
then | ||
${openssl-output:openssl} req -x509 -nodes -days 3650 \ | ||
-subj "/C=AA/ST=X/L=X/O=Dis/CN=$${:common-name}" \ | ||
-newkey rsa:1024 -keyout $${:key-file} \ | ||
-out $${:cert-file} | ||
fi | ||
update-command = $${:command} | ||
key-file = $${directory:etc}/$${:_buildout_section_name_}.key | ||
cert-file = $${directory:etc}/$${:_buildout_section_name_}.crt | ||
common-name = $${frontend-instance-config:ip} | ||
location = | ||
$${:key-file} | ||
$${:cert-file} | ||
[frontend-instance-config] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:etc}/$${:_buildout_section_name_} | ||
template = | ||
inline: | ||
:$${:port} { | ||
bind $${:ip} | ||
tls $${frontend-instance-certificate:cert-file} $${frontend-instance-certificate:key-file} | ||
log stdout | ||
errors stderr | ||
gzip | ||
# because caddy does not support upgrade http2 to websocket | ||
# https://tools.ietf.org/html/rfc8441 | ||
tls { | ||
alpn http/1.1 | ||
} | ||
root $${directory:frontend-static} | ||
browse | ||
proxy / $${theia-instance:base-url} { | ||
except $${frontend-instance-fonts:folder-name} $${frontend-instance-slapos.css:folder-name} public $${favicon.ico:filename} $${frontend-instance-logo:filename} | ||
} | ||
proxy /services $${theia-instance:base-url} { | ||
websocket | ||
} | ||
proxy /file-upload $${theia-instance:base-url} { | ||
websocket | ||
} | ||
basicauth $${frontend-instance-password:username} $${frontend-instance-password:passwd} { | ||
realm "Theia" | ||
/ | ||
} | ||
} | ||
ip = $${frontend-instance-port:ip} | ||
hostname = [$${:ip}] | ||
port = $${frontend-instance-port:port} | ||
[frontend-instance] | ||
recipe = slapos.cookbook:wrapper | ||
wrapper-path = $${directory:services}/$${:_buildout_section_name_} | ||
command-line = | ||
${caddy:output} -conf $${frontend-instance-config:rendered} -pidfile $${:pidfile} | ||
ip = $${frontend-instance-config:ip} | ||
hostname = $${frontend-instance-config:hostname} | ||
port = $${frontend-instance-config:port} | ||
pidfile = $${directory:pidfiles}/$${:_buildout_section_name_}.pid | ||
url = https://$${:hostname}:$${:port}/ | ||
[frontend-instance-fonts] | ||
; XXX caddy 1 does not seem to serve different folders at different locations | ||
; so we link fonts in static folder | ||
recipe = plone.recipe.command | ||
location = $${directory:frontend-static}/$${:folder-name} | ||
folder-name = fonts | ||
command = | ||
mkdir -p $${:location} | ||
ln -sf ${source-code-pro-fonts:location} $${:location}/source-code-pro | ||
ln -sf ${jetbrains-mono-fonts:location} $${:location}/jetbrains-mono | ||
stop-on-error = true | ||
[frontend-instance-logo] | ||
recipe = plone.recipe.command | ||
filename = logo.png | ||
full-path = $${directory:frontend-static}/$${:filename} | ||
command = | ||
cp --remove-destination ${logo.png:output} $${:full-path} | ||
stop-on-error = true | ||
[frontend-instance-slapos.css] | ||
recipe = slapos.recipe.template:jinja2 | ||
template = ${slapos.css.in:output} | ||
rendered = $${directory:frontend-static}/$${:folder-name}/slapos.css | ||
folder-name = css | ||
context = | ||
key logo_image frontend-instance-logo:filename | ||
[frontend-reload] | ||
recipe = slapos.cookbook:wrapper | ||
wrapper-path = $${directory:services}/$${:_buildout_section_name_} | ||
command-line = | ||
${bash:location}/bin/bash -c | ||
"kill -s USR1 $$(${coreutils:location}/bin/cat $${frontend-instance:pidfile}) \ | ||
&& ${coreutils:location}/bin/sleep infinity" | ||
hash-files = | ||
$${frontend-instance-config:rendered} | ||
$${frontend-instance:wrapper-path} | ||
wait-for-files = $${frontend-instance:pidfile} | ||
[favicon.ico] | ||
# generate a pseudo random favicon, different for each instance name. | ||
recipe = slapos.recipe.build | ||
install = | ||
import hashlib, shutil | ||
buildout_offline = self.buildout['buildout']['offline'] | ||
self.buildout['buildout']['offline'] = 'false' | ||
try: | ||
gravatar_url = "https://www.gravatar.com/avatar/" + hashlib.md5( | ||
'''$${slap-configuration:root-instance-title}''' | ||
).hexdigest() + "?s=256&d=retro" | ||
shutil.copy(self.download(gravatar_url), '''$${:location}''') | ||
except Exception: | ||
# Because installation should work offline, if we can't download a favicon, | ||
# just ignore this step. | ||
self.logger.exception("Error while downloading favicon, using empty one") | ||
open('''$${:location}''', 'w').close() | ||
finally: | ||
self.buildout['buildout']['offline'] = buildout_offline | ||
location = $${directory:frontend-static}/$${:filename} | ||
filename = $${:_buildout_section_name_} | ||
# Common Environment | ||
# ------------------ | ||
[common-environment] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:bin}/$${:_buildout_section_name_} | ||
mode = 0700 | ||
template = | ||
inline: | ||
#!/bin/sh | ||
. ${gowork:env.sh} | ||
# reset PS1 from gowork | ||
export PS1='$ ' | ||
export HOME=$${buildout:directory} | ||
export PATH=${python-language-server:location}/bin:${java-jdk:location}/bin:${cli-utilities:PATH}:$HOME/.cargo/bin:$PATH | ||
# Theia Backend | ||
# ------------- | ||
[theia-service-port] | ||
recipe = slapos.cookbook:free_port | ||
minimum = 3500 | ||
maximum = 3600 | ||
ip = $${instance-parameter:ipv4-random} | ||
[theia-service] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:bin}/$${:_buildout_section_name_} | ||
mode = 0700 | ||
template = | ||
inline:#!/bin/sh | ||
{{ "{% raw %}" }} | ||
{% raw %} | ||
|
||
export THEIA_WEBVIEW_EXTERNAL_ENDPOINT='{{hostname}}' | ||
{% endraw %} | ||
{{ "{% endraw %}" }} | ||
export THEIA_OPEN_EDITOR_TOKEN=$(${openssl:location}/bin/openssl rand -hex 32) | ||
export THEIA_URL=$${:base-url} | ||
export THEIA_SHELL=$${theia-shell:rendered} | ||
export TMP=$${directory:tmp} | ||
export TEMP=$TMP | ||
export LC_ALL=C.UTF-8 | ||
export TERMINFO=${ncurses:location}/lib/terminfo/ | ||
export EDITOR="${theia-open:rendered} --wait" | ||
export THEIA_DEFAULT_PLUGINS="local-dir:${theia-plugins:location}" | ||
. $${common-environment:rendered} | ||
exec ${theia-wrapper:rendered} "$@" | ||
ip = $${theia-service-port:ip} | ||
port = $${theia-service-port:port} | ||
base-url = http://$${:ip}:$${:port}/ | ||
[theia-instance] | ||
recipe = slapos.cookbook:wrapper | ||
wrapper-path = $${directory:services}/$${:_buildout_section_name_} | ||
command-line = $${theia-service:rendered} --hostname=$${:hostname} --port=$${:port} $${directory:project} | ||
hash-existing-files = | ||
${yarn.lock:output} | ||
${theia-wrapper:rendered} | ||
ip = $${instance-parameter:ipv4-random} | ||
hostname = $${:ip} | ||
port = $${theia-service:port} | ||
base-url = $${theia-service:base-url} | ||
[theia-shell] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:bin}/$${:_buildout_section_name_} | ||
mode = 0700 | ||
template = | ||
{% raw %} | ||
inline:#!{{ bash }} | ||
SHELL=$BASH | ||
# when running interactively, activate slapos configuration and reset GIT_EXEC_PATH to workaround https://github.com/eclipse-theia/theia/issues/7555 | ||
if [ $# = 0 ]; then | ||
. {{ activate }} | ||
unset GIT_EXEC_PATH | ||
set -- --rcfile {{ bashrc }} | ||
# otherwise, assume this shell is running task and add an artificial delay to workaround https://github.com/eclipse-theia/theia/issues/2961 | ||
else | ||
sleep 1 | ||
fi | ||
exec "$SHELL" "$@" | ||
{% endraw %} | ||
context = | ||
raw bash ${bash:location}/bin/bash | ||
key activate slapos-standalone-activate:rendered | ||
key bashrc theia-bashrc:rendered | ||
[theia-bashrc] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:etc}/$${:_buildout_section_name_} | ||
template = | ||
inline: | ||
# enable bash completion | ||
. ${bash-completion:location}/etc/profile.d/bash_completion.sh | ||
# source user's .bashrc | ||
[ -f ~/.bashrc ] && . ~/.bashrc | ||
depends = | ||
$${shell-setup-completion:recipe} | ||
[shell-setup-completion] | ||
recipe = plone.recipe.command | ||
stop-on-error = true | ||
command = | ||
${buildout:bin-directory}/slapos complete > $${directory:bash-completions}/slapos | ||
${buildout:bin-directory}/slapos complete --shell fish > $${directory:fish-completions}/slapos.fish | ||
# SlapOS Standalone | ||
# ----------------- | ||
[slapos-standalone-port] | ||
recipe = slapos.cookbook:free_port | ||
minimum = 4000 | ||
maximum = 4100 | ||
ip = $${instance-parameter:ipv4-random} | ||
[slapos-standalone-config] | ||
ipv4 = $${instance-parameter:ipv4-random} | ||
ipv6 = $${instance-parameter:ipv6-random} | ||
port = $${slapos-standalone-port:port} | ||
slapos-configuration = $${directory:runner}/etc/slapos.cfg | ||
computer-id = slaprunner | ||
[slapos-standalone-activate] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:bin}/$${:_buildout_section_name_} | ||
template = | ||
inline: | ||
export PATH=${buildout:bin-directory}:$PATH | ||
export SLAPOS_CONFIGURATION=$${slapos-standalone-config:slapos-configuration} | ||
export SLAPOS_CLIENT_CONFIGURATION=$SLAPOS_CONFIGURATION | ||
echo 'Standalone SlapOS for computer `$${slapos-standalone-config:computer-id}` activated' | ||
[slapos-standalone] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:bin}/$${:_buildout_section_name_} | ||
mode = 0700 | ||
template = | ||
inline:#!/bin/sh | ||
. $${common-environment:rendered} | ||
#XXX find out where the extra nodejs in theia's PATH comes from | ||
export PATH=${nodejs:location}/bin/:$PATH | ||
. $${slapos-standalone-activate:rendered} | ||
exec ${slapos-standalone:script-path} \ | ||
$${directory:runner} \ | ||
$${slapos-standalone-config:ipv4} \ | ||
$${slapos-standalone-config:ipv6} \ | ||
$${slapos-standalone-config:port} \ | ||
$${slapos-standalone-config:computer-id} \ | ||
--sr='$${instance-parameter:configuration.embedded-sr}' \ | ||
--srtype='$${instance-parameter:configuration.embedded-sr-type}' \ | ||
$${slap-connection:server-url} \ | ||
$${slap-connection:computer-id} \ | ||
$${slap-connection:partition-id} \ | ||
--key='$${slap-connection:key-file}' \ | ||
--cert='$${slap-connection:cert-file}' | ||
[slapos-standalone-instance] | ||
recipe = slapos.cookbook:wrapper | ||
wrapper-path = $${directory:services}/$${:_buildout_section_name_} | ||
command-line = $${slapos-standalone:rendered} | ||
hash-files = | ||
$${slapos-standalone:rendered} | ||
hostname = $${slapos-standalone-config:ipv4} | ||
port = $${slapos-standalone-config:port} | ||
# Slapos Standalone Autoprocessing | ||
# -------------------------------- | ||
[slapos-autorun] | ||
recipe = plone.recipe.command | ||
command = | ||
case $${:autorun} in | ||
( running ) ${buildout:bin-directory}/supervisorctl -c $${:supervisor-conf} start $${:service-name};; | ||
( stopped ) ${buildout:bin-directory}/supervisorctl -c $${:supervisor-conf} stop $${:service-name};; | ||
esac | ||
update-command = $${:command} | ||
service-name = slapos-node-auto | ||
supervisor-conf = $${directory:runner}/etc/supervisord.conf | ||
autorun = $${instance-parameter:configuration.autorun} | ||
# Theia Local Environment Setup | ||
# ----------------------------- | ||
[tasks.json] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:dot-theia}/tasks.json | ||
template = | ||
inline: | ||
{ | ||
// See https://go.microsoft.com/fwlink/?LinkId=733558 | ||
// for the documentation about the tasks.json format | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"label": "slapos node software", | ||
"detail": "Build all software supplied to the node", | ||
"type": "shell", | ||
"command": "${buildout:bin-directory}/slapos", | ||
"args": [ | ||
"node", | ||
"software", | ||
// debug mode can be enabled by commenting out this line: | ||
// "--buildout-debug", | ||
"--all" | ||
], | ||
"options": { | ||
"env": { | ||
"SLAPOS_CONFIGURATION": "$${slapos-standalone-config:slapos-configuration}", | ||
"GIT_EXEC_PATH": "" | ||
} | ||
}, | ||
"group": { | ||
"kind": "build", | ||
"isDefault": true | ||
}, | ||
"problemMatcher": [] | ||
}, | ||
{ | ||
"label": "slapos node instance", | ||
"detail": "Create all instances requested on the node", | ||
"type": "shell", | ||
"command": "${buildout:bin-directory}/slapos", | ||
"args": [ | ||
"node", | ||
"instance", | ||
// debug mode can be enabled by commenting out this line: | ||
// "--buildout-debug", | ||
"--all" | ||
], | ||
"options": { | ||
"env": { | ||
"SLAPOS_CONFIGURATION": "$${slapos-standalone-config:slapos-configuration}", | ||
"GIT_EXEC_PATH": "" | ||
} | ||
}, | ||
"problemMatcher": [], | ||
"group": { | ||
"kind": "build", | ||
"isDefault": true | ||
} | ||
} | ||
] | ||
} | ||
[slapos-repository] | ||
recipe = slapos.recipe.build:gitclone | ||
repository = https://lab.nexedi.com/nexedi/slapos.git | ||
location = $${directory:project}/slapos | ||
branch = 1.0 | ||
develop = true | ||
git-executable = ${git:location}/bin/git | ||
[settings.json] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:dot-theia}$${:_buildout_section_name_} | ||
once = $${:rendered} | ||
template = | ||
inline: | ||
{ | ||
"files.watcherExclude": { | ||
"**/.eggs/**": true, | ||
"**/.env/**": true, | ||
"**/.git/**": true, | ||
"**/node_modules/**": true, | ||
"$${directory:runner}/**":true, | ||
"$${directory:project}/runner/**":true | ||
} | ||
} | ||
[runner-link] | ||
recipe = slapos.cookbook:symbolic.link | ||
target-directory = $${directory:project} | ||
link-binary = $${directory:runner} | ||
[request-script-template] | ||
recipe = slapos.recipe.template:jinja2 | ||
rendered = $${directory:project}/$${:_buildout_section_name_}.sh | ||
mode = 0700 | ||
template = | ||
inline:#!/bin/sh | ||
# This template is generated automatically, copy it in order to supply and request. | ||
# Any manual change to this file may be lost. | ||
software_name=html5as-base #replace the software name writen in ~/srv/project/slapos/software/ | ||
software_release_uri=~/srv/project/slapos/software/$software_name/software.cfg | ||
# slapos supply is used to add the software to the software list to be supplied to a node. | ||
slapos supply $software_release_uri slaprunner | ||
# slapos request the allocation of an instance to the master. | ||
# slapos request also gets status and parameters of the instance if it has any | ||
# (slapos request is meant to be run multiple time until you get the status). | ||
slapos request $software_name'_1' $software_release_uri |