Commit 549c1636 authored by Thomas Gambier's avatar Thomas Gambier 🚴🏼

Update Release Candidate

parents 37efc4a6 b6660c58
[buildout] [buildout]
extends = extends =
../../stack/slapos.cfg ../defaults.cfg
../../component/numpy/buildout.cfg ../git/buildout.cfg
../numpy/buildout.cfg
parts = parts = cythonplus_env.sh
slapos-cookbook
template [gcc]
min_version = 8.4
[python] [python]
part = python3 part = python3
[template] # Dependencies for the Cython+ test suite
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/template.cfg
template =
inline:[buildout]
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
parts = runTestSuite
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
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}
[directory]
recipe = slapos.cookbook:mkdirectory
bin = $${buildout:directory}/bin
tmp = $${buildout:directory}/tmp
[runTestSuite]
recipe = slapos.recipe.template:jinja2
rendered = $${directory:bin}/$${:_buildout_section_name_}
template = ${runTestSuite.in:target}
mode = 0755
context =
key tmpdir directory:tmp
key slapparameter_dict slap-configuration:configuration
key cython_repository cython-repository:location
raw runTestSuite_py ${runTestSuite_py:bin-directory}/${runTestSuite_py:interpreter}
raw cython_env_sh ${cython_env.sh:rendered}
[cython-repository]
recipe = slapos.recipe.build:gitclone
repository = ${cython-repository:location}
git-executable = ${git:location}/bin/git
shared = true
[cython-repository]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/cython.git
git-executable = ${git:location}/bin/git
sparse-checkout = /.gitignore
[runTestSuite.in]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_buildout_section_name_}
md5sum = 02094e80cde9631081077fc96b401065
[runTestSuite_py]
recipe = zc.recipe.egg
eggs = erp5.util
interpreter = ${:_buildout_section_name_}
[eggs] [eggs]
recipe = zc.recipe.egg recipe = zc.recipe.egg
eggs = eggs =
...@@ -73,7 +20,13 @@ eggs = ...@@ -73,7 +20,13 @@ eggs =
coverage coverage
pycodestyle pycodestyle
[cython_env.sh] [cythonplus-repository]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/cython.git
revision = cythonplus-0.1
git-executable = ${git:location}/bin/git
[cythonplus_env.sh]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:_buildout_section_name_} rendered = ${buildout:directory}/${:_buildout_section_name_}
template = template =
...@@ -81,25 +34,25 @@ template = ...@@ -81,25 +34,25 @@ template =
{% if 'part' in gcc -%} {% if 'part' in gcc -%}
{% set path = path + ':' + gcc.prefix + '/bin' -%} {% set path = path + ':' + gcc.prefix + '/bin' -%}
{% endif -%} {% endif -%}
export PATH={{ path }}:$PATH export PATH={{ path }}$${PATH:+:$PATH}
export PYTHON={{ python }} export PYTHON={{ python }}
export PYTHONPATH={{ cythonplus_repository }}$${PYTHONPATH:+:$PYTHONPATH}
export PYTHONPATH={{ ':'.join(easy_install.working_set(eggs['eggs'].split(), [ export PYTHONPATH={{ ':'.join(easy_install.working_set(eggs['eggs'].split(), [
eggs['develop-eggs-directory'], eggs['develop-eggs-directory'],
eggs['eggs-directory'], eggs['eggs-directory'],
]).entries) }}$${PYTHONPATH:+:$PYTHONPATH} ]).entries) }}$${PYTHONPATH:+:$PYTHONPATH}
# EmbedTest needs libintl. {# Set path to libintl needed for cython EmbedTest #}
export LD_RUN_PATH={{ gettext }}/lib$${LD_RUN_PATH:+:$LD_RUN_PATH} export LD_RUN_PATH={{ gettext }}/lib$${LD_RUN_PATH:+:$LD_RUN_PATH}
export LIBRARY_PATH={{ gettext }}/lib$${LIBRARY_PATH:+:$LIBRARY_PATH} export LIBRARY_PATH={{ gettext }}/lib$${LIBRARY_PATH:+:$LIBRARY_PATH}
{##}
context = context =
section eggs eggs section eggs eggs
section gcc gcc section gcc gcc
key cythonplus_repository cythonplus-repository:location
key gettext gettext:location key gettext gettext:location
key python python:executable key python python:executable
import os os import os os
import easy_install zc.buildout.easy_install import easy_install zc.buildout.easy_install
[versions] [versions]
slapos.recipe.template = 4.4
coverage = 4.5.1 coverage = 4.5.1
pycodestyle = 2.5.0 pycodestyle = 2.5.0
...@@ -7,8 +7,8 @@ parts = garbage-collector ...@@ -7,8 +7,8 @@ parts = garbage-collector
[garbage-collector] [garbage-collector]
recipe = slapos.recipe.cmmi recipe = slapos.recipe.cmmi
shared = true shared = true
md5sum = 6f77f9fff5fb5bf96adfc1e93cd035b6 md5sum = 67a5093e2f9f381bd550aa891d00b54b
url = http://www.hboehm.info/gc/gc_source/gc-7.2g.tar.gz url = http://www.hboehm.info/gc/gc_source/gc-8.0.4.tar.gz
configure-options = configure-options =
--enable-cplusplus --enable-cplusplus
--disable-gcj-support --disable-gcj-support
......
...@@ -71,6 +71,11 @@ patches = ...@@ -71,6 +71,11 @@ patches =
version = 8.4.0 version = 8.4.0
md5sum = bb815a8e3b7be43c4a26fa89dbbd9795 md5sum = bb815a8e3b7be43c4a26fa89dbbd9795
[gcc-10.2]
<= gcc-common
version = 10.2.0
md5sum = e9fd9b1789155ad09bcf3ae747596b50
[gcc-minimal] [gcc-minimal]
<= gcc-5.5 <= gcc-5.5
configure-options = configure-options =
......
...@@ -13,8 +13,8 @@ parts = haproxy ...@@ -13,8 +13,8 @@ parts = haproxy
[haproxy] [haproxy]
recipe = slapos.recipe.cmmi recipe = slapos.recipe.cmmi
shared = true shared = true
url = http://www.haproxy.org/download/2.0/src/haproxy-2.0.17.tar.gz url = http://www.haproxy.org/download/2.0/src/haproxy-2.0.20.tar.gz
md5sum = 786a967c73cc1455c938d42fbe333bfe md5sum = 9f85ea9e6fd7d49a11cdc4c6269e10dd
configure-command = true configure-command = true
# for Linux kernel 2.6.28 and above, we use "linux-glibc" as the TARGET, # for Linux kernel 2.6.28 and above, we use "linux-glibc" as the TARGET,
# otherwise use "generic". # otherwise use "generic".
......
from ipykernel.kernelbase import Kernel
from ipykernel.kernelapp import IPKernelApp
from IPython.core.display import HTML
import requests
import json
import sys
erp5_url = None
if len(sys.argv) > 1:
erp5_url = "%s/erp5/Base_executeJupyter" % (sys.argv[1],)
class MagicInfo:
"""
Magics definition structure.
Initializes a new MagicInfo class with specific paramters to identify a magic.
"""
def __init__(self, magic_name, variable_name, send_request, request_reference, display_message):
self.magic_name = magic_name
self.variable_name = variable_name
self.send_request = send_request
self.request_reference = request_reference
self.display_message = display_message
# XXX: New magics to be added here in the dictionary.
# In this dictionary,
# key = magic_name,
# value = MagicInfo Structure corresponding to the magics
# Different parameters of the structures are :-
# magics_name(str) = Name which would be used on jupyter frontend
# variable_name(str) = Name of variable on which magic would be set in kernel
# send_request(boolean) = Magics for which requests to erp5 backend need to be made
# request_reference(boolean) = Request for notebook references(and titles) from erp5
# display_message(boolean) = If the magics need to display message after
# making request. Useful for magics which do get some
# useful content from erp5 backend and need to display
MAGICS = {
'erp5_user': MagicInfo('erp5_user', 'user', True, False, True),
'erp5_password': MagicInfo('erp5_password', 'password', True, False, True),
'erp5_url': MagicInfo('erp5_url', 'url', True, False, True),
'notebook_set_reference': MagicInfo('notebook_set_reference', 'reference', True, False, True),
'notebook_set_title': MagicInfo('notebook_set_title', 'title', False, False, True),
'my_notebooks': MagicInfo('my_notebooks', '', True, True, False)}
class ERP5Kernel(Kernel):
"""
Jupyter Kernel class to interact with erp5 backend for code from frontend.
To use this kernel with erp5, user need to install 'erp5_data_notebook' bt5
Also, handlers(aka magics) starting with '%' are predefined.
Each request to erp5 for code execution requires erp5_user, erp5_password
and reference of the notebook.
"""
implementation = 'ERP5'
implementation_version = '1.0'
language = 'ERP5'
language_version = '0.1'
language_info = {'mimetype': 'text/plain', 'name':'python'}
banner = "ERP5 integration with jupyter notebook"
def __init__(self, user=None, password=None, url=None, status_code=None,
*args, **kwargs):
super(ERP5Kernel, self).__init__(*args, **kwargs)
self.user = user
self.password = password
# By default use URL provided by buildout during initiation
# It can later be overridden
if url is None:
self.url = erp5_url
else:
self.url = url
self.status_code = status_code
self.reference = None
self.title = None
# Allowed HTTP request code list for making request to erp5 from Kernel
# This list should be to used check status_code before making requests to erp5
self.allowed_HTTP_request_code_list = range(500, 511)
# Append request code 200 in the allowed HTTP status code list
self.allowed_HTTP_request_code_list.append(200)
def display_response(self, response=None):
"""
Dispays the stream message response to jupyter frontend.
"""
if response:
stream_content = {'name': 'stdout', 'text': response}
self.send_response(self.iopub_socket, 'stream', stream_content)
def set_magic_attribute(self, magic_info=None, code=None):
"""
Set attribute for magic which are necessary for making requests to erp5.
Catch errors and display message. Since user is in contact with jupyter
frontend, so its better to catch exceptions and dispaly messages than to
let them fail in backend and stuck the kernel.
For a making a request to erp5, we need -
erp5_url, erp5_user, erp5_password, notebook_set_reference
"""
# Set attributes only for magic who do have any varible to set value to
if magic_info.variable_name:
try:
# Get the magic value recived via code from frontend
magic_value = code.split()[1]
# Set magic_value to the required attribute
if magic_info.magic_name == 'notebook_set_reference':
required_attributes = ['url', 'password', 'user']
missing_attributes = []
for attribute in required_attributes:
if not getattr(self, attribute):
missing_attributes.append(attribute)
if missing_attributes != []:
self.response = "You still haven't entered all required magics. \
Please do so before inputting your reference."
else:
if self.check_existing_reference(reference=magic_value):
self.response = 'WARNING: You already have a notebook with \
reference %s. It might be a good idea to use different references for new \
notebooks. \n' % magic_value
else:
self.response = ''
setattr(self, magic_info.variable_name , magic_value)
self.response = self.response + 'Your %s is %s. '%(magic_info.magic_name, magic_value)
elif magic_info.magic_name != 'erp5_password':
setattr(self, magic_info.variable_name , magic_value)
self.response = 'Your %s is %s. '%(magic_info.magic_name, magic_value)
else:
setattr(self, magic_info.variable_name , magic_value)
self.response = ""
# Catch exception while setting attribute and set message in response
except AttributeError:
self.response = 'Please enter %s magic value'%magic_info.variable_name
# Catch IndexError while getting magic_value and set message in response object
except IndexError:
self.response = 'Empty value for %s magic'%magic_info.variable_name
# Catch all other exceptions and set error_message in response object
# XXX: Might not be best way, but its better to display error to the user
# via notebook frontend than to fail in backend and stuck the Kernel without
# any failure message to user.
except Exception as e:
self.response = str(e)
# Display the message/response from this fucntion before moving forward so
# as to keep track of the status
if self.response != "":
self.display_response(response=(self.response + '\n'))
def check_required_attributes(self):
"""
Check if the required attributes for making a request are already set or not.
Display message to frontend to provide with the values in case they aren't.
This function can be called anytime to check if the attributes are set. The
output result will be in Boolean form.
Also, in case any of attribute is not set, call to display_response would be
made to ask user to enter value.
"""
result_list = []
required_attributes = ['url', 'user', 'password', 'reference']
missing_attributes = []
# Set response to empty so as to flush the response set by some earlier fucntion call
self.response = ''
# Loop to check if the required attributes are set
for attribute in required_attributes:
if getattr(self, attribute):
result_list.append(True)
else:
# Set response/message for attributes which aren't set
missing_attributes.append(attribute)
result_list.append(False)
# Compare result_list to get True for all True results and False for any False result
check_attributes = all(result_list)
if check_attributes:
self.response = 'You have entered all required magics. You may now use your notebook.'
else:
self.response = '''You have these required magics remaining: %s. \n''' % (
', '.join(map(str, missing_attributes)))
# Display response to frontend before moving forward
self.display_response(response=(self.response + '\n'))
return check_attributes
def make_erp5_request(self, request_reference=False, display_message=True,
code=None, message=None, title=None, *args, **kwargs):
"""
Function to make request to erp5 as per the magics.
Should return the response json object.
"""
try:
erp5_request = requests.post(
self.url,
verify=False,
auth=(self.user, self.password),
data={
'python_expression': code,
'reference': self.reference,
'title': self.title,
'request_reference': request_reference,
'store_history': kwargs.get('store_history')
})
# Set value for status_code for self object which would later be used to
# dispaly response after statement check
self.status_code = erp5_request.status_code
# Dispaly error response in case the request give any other status
# except 200 and 5xx(which is for errors on server side)
if self.status_code not in self.allowed_HTTP_request_code_list:
self.response = '''Error code %s on request to ERP5,\n
check credentials or ERP5 family URL'''%self.status_code
else:
# Set value of self.response to the given value in case response from function
# call. In all other case, response should be the content from request
if display_message and message:
self.response = message
else:
self.response = erp5_request.content
except requests.exceptions.RequestException as e:
self.response = str(e)
def do_execute(self, code, silent, store_history=True, user_expressions=None,
allow_stdin=False):
"""
Validate magic and call functions to make request to erp5 backend where
the code is being executed and response is sent back which is then sent
to jupyter frontend.
"""
# By default, take the status of response as 'ok' so as show the responses
# for erp5_url and erp5_user on notebook frontend as successful response.
status = 'ok'
if not silent:
# Remove spaces and newlines from both ends of code
code = code.strip()
extra_data_list = []
print_result = {}
displayhook_result = {}
if code.startswith('%'):
# No need to try-catch here as its already been taken that the code
# starts-with '%', so we'll get magic_name, no matter what be after '%'
magic_name = code.split()[0][1:]
magics_name_list = [magic.magic_name for magic in MAGICS.values()]
# Check validation of magic
if magic_name and magic_name in magics_name_list:
# Get MagicInfo object related to the magic
magic_info = MAGICS.get(magic_name)
# Function call to set the required magics
self.set_magic_attribute(magic_info=magic_info, code=code)
# Call to check if the required_attributes are set
checked_attribute = self.check_required_attributes()
if checked_attribute and magic_info.send_request:
# Call the function to send request to erp5 with the arguments given
self.make_erp5_request(message='Please proceed\n',
request_reference=magic_info.request_reference,
display_message=magic_info.display_message)
# Display response from erp5 request for magic
# Since this response would be either success message or failure
# error message, both of which are string type, so, we can simply
# display the stream response.
if self.response != 'Please proceed\n':
self.display_response(response=self.response)
else:
# Set response if there is no magic or the magic name is not in MAGICS
self.response = 'Invalid Magics'
self.display_response(response=self.response)
else:
# Check for status_code before making request to erp5 and make request in
# only if the status_code is in the allowed_HTTP_request_code_list
if self.status_code in self.allowed_HTTP_request_code_list:
self.make_erp5_request(code=code, store_history=store_history)
# For 200 status_code, Kernel will receive predefined format for data
# from erp5 which is either json of result or simple result string
if self.status_code == 200:
mime_type = 'text/plain'
try:
content = json.loads(self.response)
# Example format for the json result we are expecting is :
# content = {
# "status": "ok",
# "ename": null,
# "evalue": null,
# "traceback": null,
# "code_result": "",
# "print_result": {},
# "displayhook_result": {},
# "mime_type": "text/plain",
# "extra_data_list": []
# }
# So, we can easily use any of the key to update values as such.
# Getting code_result for succesfull execution of code
code_result = content['code_result']
print_result = content['print_result']
displayhook_result = content['displayhook_result']
# Update mime_type with the mime_type from the http response result
# Required in case the mime_type is anything other than 'text/plain'
mime_type = content['mime_type']
extra_data_list = content.get('extra_data_list', [])
# Display to frontend the error message for content status as 'error'
if content['status']=='error':
reply_content = {
'status': 'error',
'execution_count': self.execution_count,
'ename': content['ename'],
'evalue': content['evalue'],
'traceback': content['traceback']}
self.send_response(self.iopub_socket, u'error', reply_content)
return reply_content
# Catch exception for content which isn't json
except ValueError:
content = self.response
code_result = content
print_result = {'data':{'text/plain':content}, 'metadata':{}}
# Display basic error message to frontend in case of error on server side
else:
self.make_erp5_request(code=code)
code_result = "Error at Server Side"
print_result = {'data':{'text/plain':'Error at Server Side'}, 'metadata':{}}
mime_type = 'text/plain'
# For all status_code except allowed_HTTP_response_code_list show unauthorized message
else:
code_result = 'Unauthorized access'
print_result = {'data':{'text/plain':'Unauthorized access'}, 'metadata':{}}
mime_type = 'text/plain'
if print_result.get('data'):
self.send_response(self.iopub_socket, 'display_data', print_result)
if displayhook_result.get('data'):
displayhook_result['execution_count'] = self.execution_count
self.send_response(self.iopub_socket, 'execute_result', displayhook_result)
for extra_data in extra_data_list:
self.send_response(self.iopub_socket, 'display_data', extra_data)
reply_content = {
'status': status,
# The base class increments the execution count
'execution_count': self.execution_count,
'payload': [],
'user_expressions': {}}
return reply_content
# Checks the ERP5 site if there are existing notebooks with the same reference.
# Returns True if there are.
def check_existing_reference(self, reference):
if reference == None:
return False
modified_url = self.url[:self.url.rfind('/')] + '/Base_checkExistingReference'
result = True
try:
erp5_request = requests.post(
modified_url,
verify=False,
auth=(self.user, self.password),
data={
'reference': reference,
})
result = erp5_request.content
except requests.exceptions.RequestException as e:
self.response = str(e)
return result
if __name__ == '__main__':
IPKernelApp.launch_instance(kernel_class=ERP5Kernel)
This directory is only temporary (until ERP5 is Python3) and will not actively
be maintained.
It has to be removed once ERP5 uses `software/jupyter` or do not use jupyter at
all.
[buildout]
extends =
buildout.hash.cfg
../../stack/slapos.cfg
../openssl/buildout.cfg
../jupyter/buildout.cfg
../../stack/monitor/buildout.cfg
parts +=
slapos-cookbook
jupyter
jupyter-notebook-initialized-scripts
instance-jupyter-notebook
[gcc]
# Always build GCC for Fortran (see openblas).
max_version = 0
[jupyter]
python_executable = ${buildout:bin-directory}/${:interpreter}
[download-file-base]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:filename}
download-only = true
mode = 0644
[jupyter-notebook-config]
<= download-file-base
[jupyter-set-password]
<= download-file-base
[erp5-kernel]
<= download-file-base
[kernel-json]
<= download-file-base
[custom-js]
<= download-file-base
[instance-jupyter-notebook]
recipe = slapos.recipe.template:jinja2
template = ${:_profile_base_location_}/${:filename}
rendered = ${buildout:directory}/template.cfg
mode = 0644
context =
key bin_directory buildout:bin-directory
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
key openssl_output openssl-output:openssl
key python_executable jupyter:python_executable
key jupyter_config_location jupyter-notebook-config:location
key jupyter_config_filename jupyter-notebook-config:filename
key jupyter_set_password_location jupyter-set-password:location
key jupyter_set_password_filename jupyter-set-password:filename
key erp5_kernel_location erp5-kernel:location
key erp5_kernel_filename erp5-kernel:filename
key kernel_json_location kernel-json:location
key kernel_json_filename kernel-json:filename
key custom_js_location custom-js:location
key custom_js_filename custom-js:filename
key monitor_template_rendered buildout:directory
[versions]
Pygments = 2.2.0
astor = 0.5
backports-abc = 0.5
backports.functools-lru-cache = 1.6.1
backports.shutil-get-terminal-size = 1.0.0
cycler = 0.10.0
ipykernel = 4.5.2
ipython = 5.3.0
ipython-genutils = 0.1.0
ipywidgets = 6.0.0
jupyter-client = 5.0.0
jupyter-core = 4.3.0
jupyterlab = 0.26.3
jupyterlab-launcher = 0.3.1
matplotlib = 2.1.2
mistune = 0.7.3
nbformat = 4.3.0
notebook = 4.4.1
pandas = 0.19.2
plone.recipe.command = 1.1
prompt-toolkit = 1.0.13
ptyprocess = 0.5.1
pyzmq = 16.0.2
scikit-learn = 0.18.1
seaborn = 0.7.1
simplegeneric = 0.8.1
statsmodels = 0.8.0
terminado = 0.6
tornado = 4.4.2
traitlets = 4.3.2
widgetsnbextension = 2.0.0
# numpy >= 1.13.1 is required for numpy.core.multiarray
numpy = 1.13.1
# Required by:
# tornado==4.4.2
certifi = 2020.6.20
# Required by:
# notebook==4.3.2
# nbconvert 4.2.0 depends on entrypoints egg that is not available as tar/zip source.
nbconvert = 4.1.0
# Required by:
# ipython==5.3.0
pathlib2 = 2.2.1
# Required by:
# statsmodels==0.8.0
patsy = 0.4.1
# Required by:
# ipython==5.3.0
pexpect = 4.2.1
# Required by:
# ipython==5.3.0
pickleshare = 0.7.4
# Required by:
# matplotlib==2.1.2
# pandas==0.19.2
python-dateutil = 2.6.0
# Required by:
# pathlib2==2.2.1
scandir = 1.5
# Required by:
# statsmodels==0.8.0
scipy = 0.19.0
# Required by:
# tornado==4.4.2
singledispatch = 3.4.0.3
# Required by:
# prompt-toolkit==1.0.13
wcwidth = 0.1.7
jupyter = 1.0.0
jupyter-console = 5.1.0
# Required by:
# jupyter==1.0.0
qtconsole = 4.3.0
et-xmlfile = 1.0.1
h5py = 2.7.1
mpmath = 1.0.0
openpyxl = 2.5.2
sympy = 1.1.1
xlrd = 1.1.0
# Required by:
# openpyxl==2.5.2
jdcal = 1.4
# THIS IS NOT A BUILDOUT FILE, despite purposedly using a compatible syntax.
# The only allowed lines here are (regexes):
# - "^#" comments, copied verbatim
# - "^[" section beginings, copied verbatim
# - lines containing an "=" sign which must fit in the following categorie.
# - "^\s*filename\s*=\s*path\s*$" where "path" is relative to this file
# Copied verbatim.
# - "^\s*hashtype\s*=.*" where "hashtype" is one of the values supported
# by the re-generation script.
# Re-generated.
# - other lines are copied verbatim
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# section inheritance (< = ...) are NOT supported (but you should really
# not need these here).
[instance-jupyter-notebook]
filename = instance.cfg.in
md5sum = 1d5fe6cc4e48672ae7be1c223794a932
[jupyter-notebook-config]
filename = jupyter_notebook_config.py.jinja
md5sum = 720e90a829c63371696bc3009917a743
[jupyter-set-password]
filename = jupyter_set_password.cgi.jinja
md5sum = ac10fbcf790bd8e58750cfdd069812d2
[erp5-kernel]
filename = ERP5kernel.py
md5sum = 7d5309fe79afbcb455c0d8181b42e56c
[kernel-json]
filename = kernel.json.jinja
md5sum = 33547be93a67530165e079dc3ecfdac3
[custom-js]
filename = custom.js
md5sum = 147ccce38f7d7cf10664975d0dd80e33
// leave at least 2 line with only a star on it below, or doc generation fails
/**
*
*
* Placeholder for custom user javascript
* mainly to be overridden in profile/static/custom/custom.js
* This will always be an empty file in IPython
*
* User could add any javascript in the `profile/static/custom/custom.js` file.
* It will be executed by the ipython notebook at load time.
*
* Same thing with `profile/static/custom/custom.css` to inject custom css into the notebook.
*
*
* The object available at load time depend on the version of IPython in use.
* there is no guaranties of API stability.
*
* The example below explain the principle, and might not be valid.
*
* Instances are created after the loading of this file and might need to be accessed using events:
* define([
* 'base/js/namespace',
* 'base/js/events'
* ], function(IPython, events) {
* events.on("app_initialized.NotebookApp", function () {
* IPython.keyboard_manager....
* });
* });
*
* __Example 1:__
*
* Create a custom button in toolbar that execute `%qtconsole` in kernel
* and hence open a qtconsole attached to the same kernel as the current notebook
*
* define([
* 'base/js/namespace',
* 'base/js/events'
* ], function(IPython, events) {
* events.on('app_initialized.NotebookApp', function(){
* IPython.toolbar.add_buttons_group([
* {
* 'label' : 'run qtconsole',
* 'icon' : 'icon-terminal', // select your icon from http://fortawesome.github.io/Font-Awesome/icons
* 'callback': function () {
* IPython.notebook.kernel.execute('%qtconsole')
* }
* }
* // add more button here if needed.
* ]);
* });
* });
*
* __Example 2:__
*
* At the completion of the dashboard loading, load an unofficial javascript extension
* that is installed in profile/static/custom/
*
* define([
* 'base/js/events'
* ], function(events) {
* events.on('app_initialized.DashboardApp', function(){
* require(['custom/unofficial_extension.js'])
* });
* });
*
* __Example 3:__
*
* Use `jQuery.getScript(url [, success(script, textStatus, jqXHR)] );`
* to load custom script into the notebook.
*
* // to load the metadata ui extension example.
* $.getScript('/static/notebook/js/celltoolbarpresets/example.js');
* // or
* // to load the metadata ui extension to control slideshow mode / reveal js for nbconvert
* $.getScript('/static/notebook/js/celltoolbarpresets/slideshow.js');
*
*
* @module IPython
* @namespace IPython
* @class customjs
* @static
*/
$([Jupyter.events]).on('notebook_loaded.Notebook', function(){
var kernelname = Jupyter.notebook.kernel_selector.current_selection;
var display_text="<div class='output_subarea output_text output_result'>\
<pre>Follow these steps to customize your notebook with ERP5 kernel :-</br>\
1. Make sure you have 'erp5_data_notebook' business template installed in your ERP5</br>\
2. <b>%erp5_user &lt;your_erp5_username&gt;</b></br>\
3. <b>%erp5_password &lt;your_erp5_password&gt;</b></br>\
4. <b>%notebook_set_reference &lt;your_notebook_reference&gt;</b></br>\
It would be better to set the reference to match with erp5 reference pattern.</br>\
5. As soon as you see 'Please Proceed' message you can now access your erp5 using notebook.</br>\
<p><u>OTHER USEFUL MAGICS</u> -</br>\
<b>%my_notebooks</b> -This is used to display all the notebooks created by the specific user.</br>\
<b>%notebook_set_title</b> -This sets the title of the current notebook.</br>\
NOTE: Do not dynamically alter imported module objects as they are not being saved in DB, </br>\
so changes to them would be disregarded and would throw an error.</br>\
<p><u>About classes, functions and global state on modules:</u></p>\
Your code is going to be executed by ERP5, which can have many nodes </br>\
and there is no guarantee that your code is always going to be executed by the same server.</br>\
This means that objects which cannot be stored in the ZODB, like functions, classes and modules </br>\
won't be available across nodes. To solve this issue, you need to use a special object </br>\
called 'environment' to store your global setup. This object was designed to hold global </br>\
state and restore it for each code cell. Example:</br></br>\
<b>def my_setup():</br>\
# import modules, define functions and classes</br>\
# and set global state on modules</br>\
# return dict of variables to be available in code cells</br>\
{'my_var': 1}</br>\
environment.define(my_setup, 'my custom setup')</b></br></br>\
After you execute this cell, the <b>my_setup</b> function will run before each of the</br>\
following cells and the <b>my_var</b> variable will be created and set to 1.</br></br>\
<b>WARNING:</b> it is not recommended to have too many setup functions in the environment, </br>\
because they will be executed in every code cell and can cause a substantial slow down.\
</pre></div>";
if (kernelname=="erp5"){
$('div#notebook-container').prepend(display_text);
}
});
[buildout]
parts =
instance
jupyter_notebook
read-knowledge0
publish-connection-parameter
jupyter-notebook-config
erp5-kernel
kernel-json
custom-js
monitor-base
extends =
{{ monitor_template_rendered }}/template-monitor.cfg
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[slapconfiguration]
recipe = slapos.cookbook:slapconfiguration.serialised
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}
# ERP5 URL to use in Jupyter by default
# default value is empty - which means no default ERP5 URL
configuration.erp5-url =
[instance-parameter]
port = 8888
host = ${slapconfiguration:ipv6-random}
cert_file = ${generate-certificate:cert_file}
key_file = ${generate-certificate:key_file}
logfile = ${directory:log}/jupyter_notebook.log
notebook_dir = ${directory:notebook_dir}
[dynamic-jinja2-template-base]
recipe = slapos.recipe.template:jinja2
mode = 0644
[generate-certificate]
; TODO: there is a slapos recipe to generate certificates. Use it instead
recipe = plone.recipe.command
command =
if [ ! -e ${instance-parameter:key_file} ]
then
{{ openssl_output }} req -x509 -nodes -days 3650 \
-subj "/C=AA/ST=X/L=X/O=Dis/CN=${instance-parameter:host}" \
-newkey rsa:1024 -keyout ${instance-parameter:key_file} \
-out ${instance-parameter:cert_file}
fi
update-command = ${:command}
cert_file = ${directory:etc}/jupyter_cert.crt
key_file = ${directory:etc}/jupyter_cert.key
[instance]
recipe = slapos.cookbook:wrapper
command-line =
{{ bin_directory }}/jupyter-lab
--no-browser
--ip=${instance-parameter:host}
--port=${instance-parameter:port}
--port-retries=0
--certfile=${instance-parameter:cert_file}
--keyfile=${instance-parameter:key_file}
--notebook-dir=${instance-parameter:notebook_dir}
--log-level="DEBUG"
wrapper-path = ${directory:service}/jupyter-lab
environment =
JUPYTER_PATH=${directory:jupyter_dir}
JUPYTER_CONFIG_DIR=${directory:jupyter_config_dir}
JUPYTER_RUNTIME_DIR=${directory:jupyter_runtime_dir}
LANG=C.UTF-8
[jupyter-notebook-config]
<= dynamic-jinja2-template-base
template = {{ jupyter_config_location }}/{{ jupyter_config_filename }}
rendered = ${directory:jupyter_config_dir}/jupyter_notebook_config.py
mode = 0744
context =
raw config_cfg ${buildout:directory}/knowledge0.cfg
[directory]
recipe = slapos.cookbook:mkdirectory
home = ${buildout:directory}
etc = ${:home}/etc
var = ${:home}/var
script = ${:etc}/run/
service = ${:etc}/service
log = ${:var}/log
notebook_dir = ${:var}/notebooks
# Add folders to explicitly define jupyter directory
jupyter_dir = ${:home}/jupyter
jupyter_config_dir = ${:jupyter_dir}/etc
jupyter_kernel_dir = ${:jupyter_dir}/kernels
jupyter_runtime_dir = ${:jupyter_dir}/runtime
jupyter_custom_dir = ${:jupyter_config_dir}/custom
jupyter_nbextensions_dir = ${:jupyter_dir}/nbextensions
erp5_kernel_dir = ${:jupyter_kernel_dir}/ERP5
[jupyter_notebook]
# This part is called like this because knowledge0.write uses the part name for
# the section name in the config file.
recipe = slapos.cookbook:zero-knowledge.write
password =
filename = knowledge0.cfg
[read-knowledge0]
recipe = slapos.cookbook:zero-knowledge.read
filename = knowledge0.cfg
password =
[monitor-instance-parameter]
monitor-base-url = ${monitor-frontend-promise:url}
# In case you're using a developer instance you should edit these in:
# monitor-base-url = ${monitor-httpd-conf-parameter:url}
# cors-domains = softinstXXXXX.host.vifib.net (or equivalent)
# interface-url = https://softinstXXXXX.host.vifib.net/erp5/web_site_module/monitoring_rjs_unsafe
instance-configuration =
raw jupyter-password ${read-knowledge0:password}
[publish-connection-parameter]
recipe = slapos.cookbook:publish.serialised
jupyter-classic-url = https://[${instance-parameter:host}]:${instance-parameter:port}/tree
url = ${:jupyter-classic-url}
jupyterlab-url = https://[${instance-parameter:host}]:${instance-parameter:port}/lab
[erp5-kernel]
recipe = slapos.cookbook:symbolic.link
link-binary = {{ erp5_kernel_location }}/{{ erp5_kernel_filename }}
target-directory = ${directory:erp5_kernel_dir}
[kernel-json]
<= dynamic-jinja2-template-base
template = {{ kernel_json_location }}/{{ kernel_json_filename }}
rendered = ${directory:erp5_kernel_dir}/kernel.json
# Use python2.7 executable bin file for kernel config
context =
raw python_executable {{ python_executable }}
raw kernel_dir ${erp5-kernel:target-directory}/{{ erp5_kernel_filename }}
key erp5_url slapconfiguration:configuration.erp5-url
raw display_name ERP5
raw language_name python
[custom-js]
recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:jupyter_custom_dir}
link-binary = {{ custom_js_location }}/custom.js
'''
This script initializes Jupyter's configuration such as passwords and other
things. It is run by IPython hence why it can use functions like get_config().
'''
import ConfigParser
import random
from notebook.auth import passwd
import os
def random_password(length = 10):
result = ""
for i in range(0, length):
result = result + chr(random.randint(0, 25) + ord('a'))
return result
knowledge_0 = '{{ config_cfg }}'
if not os.path.exists(knowledge_0):
print "Your software does <b>not</b> embed 0-knowledge. \
This interface is useless in this case</body></html>"
exit(0)
c = get_config()
parser = ConfigParser.ConfigParser()
parser.read(knowledge_0)
if not parser.has_section("jupyter_notebook"):
parser.add_section("jupyter_notebook")
if not parser.has_option("jupyter_notebook", "password") or \
parser.get("jupyter_notebook", "password") == "":
parser.set("jupyter_notebook", "password", random_password())
c.NotebookApp.password = passwd(parser.get("jupyter_notebook", "password"))
with open(knowledge_0, 'w') as file:
parser.write(file)
...@@ -61,4 +61,3 @@ print """<div class="pure-control-group"> ...@@ -61,4 +61,3 @@ print """<div class="pure-control-group">
<script type="text/javascript" src="static/monitor-register.js"></script> <script type="text/javascript" src="static/monitor-register.js"></script>
</body></html> </body></html>
""" """
{
"argv": [
"{{python_executable}}",
"{{kernel_dir}}",
"{{erp5_url}}",
"-f",
"{connection_file}"
],
"display_name": "{{display_name}}",
"language": "{{language_name}}",
"language_info": {"name": "python"}
}
...@@ -8,8 +8,8 @@ parts = logrotate ...@@ -8,8 +8,8 @@ parts = logrotate
[logrotate] [logrotate]
recipe = slapos.recipe.cmmi recipe = slapos.recipe.cmmi
shared = true shared = true
url = https://github.com/logrotate/logrotate/releases/download/3.15.0/logrotate-3.15.0.tar.xz url = https://github.com/logrotate/logrotate/releases/download/3.17.0/logrotate-3.17.0.tar.xz
md5sum = 320046f0b9fc38337e8827d4c5a866a0 md5sum = ac2a7151fc8a187201872358a20a2813
# BBB this is only for backward-compatibility. # BBB this is only for backward-compatibility.
post-install = post-install =
ln -nsf . @@LOCATION@@/usr ln -nsf . @@LOCATION@@/usr
......
diff --git a/config.c b/config.c
index e6d5d1d..dd004a9 100644
--- a/config.c
+++ b/config.c
@@ -519,7 +519,11 @@ static int readConfigFile(const char *configFile, struct logInfo *defConfig)
length arrays -- of course, if we aren't run setuid it doesn't
matter much */
+#ifdef O_CLOEXEC
fd = open(configFile, O_RDONLY | O_CLOEXEC);
+#else
+ fd = open(configFile, O_RDONLY);
+#endif
if (fd < 0) {
message(MESS_ERROR, "failed to open config file %s: %s\n",
configFile, strerror(errno));
...@@ -17,8 +17,8 @@ parts = ...@@ -17,8 +17,8 @@ parts =
[openssl] [openssl]
recipe = slapos.recipe.cmmi recipe = slapos.recipe.cmmi
shared = true shared = true
url = https://www.openssl.org/source/openssl-1.1.1g.tar.gz url = https://www.openssl.org/source/openssl-1.1.1i.tar.gz
md5sum = 76766e98997660138cdaf13a187bd234 md5sum = 08987c3cf125202e2b0840035efb392c
location = @@LOCATION@@ location = @@LOCATION@@
# 'prefix' option to override --openssldir/--prefix (which is useful # 'prefix' option to override --openssldir/--prefix (which is useful
# when combined with DESTDIR). Used by slapos.package.git/obs # when combined with DESTDIR). Used by slapos.package.git/obs
......
...@@ -8,19 +8,19 @@ extends = ...@@ -8,19 +8,19 @@ extends =
../patch/buildout.cfg ../patch/buildout.cfg
../pcre/buildout.cfg ../pcre/buildout.cfg
../cyrus-sasl/buildout.cfg ../cyrus-sasl/buildout.cfg
../m4/buildout.cfg
[postfix] [postfix]
recipe = slapos.recipe.cmmi recipe = slapos.recipe.cmmi
shared = true shared = true
url = ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-2.11.6.tar.gz url = ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-3.5.8.tar.gz
md5sum = c3277d05b78eaaf5955406bc7b6d2b9f md5sum = c7c55ccc1db2a30d35c3867c21fe7109
location = @@LOCATION@@ location = @@LOCATION@@
patch-options = -p1 patch-options = -p1
patches = patches =
${:_profile_base_location_}/noroot.patch#738bcc97b8044c45b58708bdf3a84b8e ${:_profile_base_location_}/noroot.patch#05fc6333e05576ea8e5a49f27a6ef951
${:_profile_base_location_}/skip-libdb-check.patch#f7fdbd8787874b535fee548b0139c0d8
configure-command = make configure-command = make
configure-options = makefiles CCARGS='-DUSE_SASL_AUTH -DUSE_CYRUS_SASL -DUSE_TLS -DHAS_PCRE -DHAS_DB -I${libdb:location}/include -I${pcre:location}/include -I${openssl-1.0:location}/include -I${cyrus-sasl:location}/include/sasl' AUXLIBS='-L${openssl-1.0:location}/lib -L${pcre:location}/lib -L${libdb:location}/lib -L${cyrus-sasl:location}/lib -lssl -lpcre -ldb -lcrypto -lsasl2 -Wl,-rpath=${openssl-1.0:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${libdb:location}/lib -Wl,-rpath=${cyrus-sasl:location}/lib' configure-options = makefiles CCARGS='-DUSE_SASL_AUTH -DUSE_CYRUS_SASL -DUSE_TLS -DHAS_PCRE -DHAS_DB -I${libdb:location}/include -I${pcre:location}/include -I${openssl-1.0:location}/include -I${cyrus-sasl:location}/include/sasl' AUXLIBS='-L${openssl-1.0:location}/lib -L${pcre:location}/lib -L${libdb:location}/lib -L${cyrus-sasl:location}/lib -lssl -lpcre -ldb -lcrypto -lsasl2 -Wl,-rpath=${openssl-1.0:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${libdb:location}/lib -Wl,-rpath=${cyrus-sasl:location}/lib'
make-targets = non-interactive-package install_root=${:location} make-targets = non-interactive-package install_root=${:location}
environment = environment =
PATH=${patch:location}/bin:%(PATH)s PATH=${patch:location}/bin:${m4:location}/bin:%(PATH)s
...@@ -2,16 +2,16 @@ diff --git a/src/global/mail_params.c b/src/global/mail_params.c ...@@ -2,16 +2,16 @@ diff --git a/src/global/mail_params.c b/src/global/mail_params.c
index 2d91977..0f06298 100644 index 2d91977..0f06298 100644
--- a/src/global/mail_params.c --- a/src/global/mail_params.c
+++ b/src/global/mail_params.c +++ b/src/global/mail_params.c
@@ -721,7 +721,9 @@ void mail_params_init() @@ -911,7 +911,9 @@ void mail_params_init()
check_default_privs(); check_default_privs();
check_mail_owner(); check_mail_owner();
check_sgid_group(); check_sgid_group();
+ /* + /*
check_overlap(); check_overlap();
+ */ + */
#ifdef HAS_DB
dict_db_cache_size = var_db_read_buf; dict_db_cache_size = var_db_read_buf;
#endif dict_lmdb_map_size = var_lmdb_map_size;
inet_windowsize = var_inet_windowsize;
diff --git a/src/master/master.c b/src/master/master.c diff --git a/src/master/master.c b/src/master/master.c
index a9d5d1b..db88c55 100644 index a9d5d1b..db88c55 100644
--- a/src/master/master.c --- a/src/master/master.c
...@@ -29,12 +29,13 @@ index a9d5d1b..db88c55 100644 ...@@ -29,12 +29,13 @@ index a9d5d1b..db88c55 100644
/* /*
* Process JCL. * Process JCL.
@@ -392,8 +392,10 @@ int main(int argc, char **argv) @@ -433,9 +433,11 @@ int main(int argc, char **argv)
* all MTA processes cleanly. Give up if we can't separate from our * all MTA processes cleanly. Give up if we can't separate from our
* parent process. We're not supposed to blow away the parent. * parent process. We're not supposed to blow away the parent.
*/ */
+ /* + /*
if (debug_me == 0 && master_detach != 0 && setsid() == -1 && getsid(0) != getpid()) if (init_mode == 0 && debug_me == 0 && master_detach != 0
&& setsid() == -1 && getsid(0) != getpid())
msg_fatal("unable to set session and process group ID: %m"); msg_fatal("unable to set session and process group ID: %m");
+ */ + */
......
diff --git a/makedefs b/makedefs
index dd5f256..e90880e 100644
--- a/makedefs
+++ b/makedefs
@@ -299,13 +299,13 @@ case "$SYSTEM.$RELEASE" in
elif [ -f /usr/include/db/db.h ]
then
CCARGS="$CCARGS -I/usr/include/db"
- else
+ #else
# No, we're not going to try db1 db2 db3 etc.
# On a properly installed system, Postfix builds
# by including <db.h> and by linking with -ldb
- echo "No <db.h> include file found." 1>&2
- echo "Install the appropriate db*-devel package first." 1>&2
- exit 1
+ #echo "No <db.h> include file found." 1>&2
+ #echo "Install the appropriate db*-devel package first." 1>&2
+ #exit 1
fi
SYSLIBS="-ldb"
;;
@@ -372,12 +372,12 @@ EOF
elif [ -f /usr/include/db/db.h ]
then
CCARGS="$CCARGS -I/usr/include/db"
- else
+ #else
# On a properly installed system, Postfix builds
# by including <db.h> and by linking with -ldb
- echo "No <db.h> include file found." 1>&2
- echo "Install the appropriate db*-devel package first." 1>&2
- exit 1
+ #echo "No <db.h> include file found." 1>&2
+ #echo "Install the appropriate db*-devel package first." 1>&2
+ #exit 1
fi
SYSLIBS="-ldb"
;;
@@ -403,12 +403,12 @@ EOF
elif [ -f /usr/include/db/db.h ]
then
CCARGS="$CCARGS -I/usr/include/db"
- else
+ #else
# On a properly installed system, Postfix builds
# by including <db.h> and by linking with -ldb
- echo "No <db.h> include file found." 1>&2
- echo "Install the appropriate db*-devel package first." 1>&2
- exit 1
+ #echo "No <db.h> include file found." 1>&2
+ #echo "Install the appropriate db*-devel package first." 1>&2
+ #exit 1
fi
SYSLIBS="-ldb"
;;
...@@ -7,6 +7,7 @@ parts = ...@@ -7,6 +7,7 @@ parts =
[socat] [socat]
recipe = slapos.recipe.cmmi recipe = slapos.recipe.cmmi
shared = true
url = http://www.dest-unreach.org/socat/download/socat-${:version}.tar.gz url = http://www.dest-unreach.org/socat/download/socat-${:version}.tar.gz
version = 1.7.3.2 version = 1.7.3.2
md5sum = aec3154f7854580cfab0c2d81e910519 md5sum = aec3154f7854580cfab0c2d81e910519
......
...@@ -6,6 +6,7 @@ extends = ...@@ -6,6 +6,7 @@ extends =
../make/buildout.cfg ../make/buildout.cfg
../ncurses/buildout.cfg ../ncurses/buildout.cfg
../openssl/buildout.cfg ../openssl/buildout.cfg
../patch/buildout.cfg
../pcre/buildout.cfg ../pcre/buildout.cfg
../perl/buildout.cfg ../perl/buildout.cfg
../pkgconfig/buildout.cfg ../pkgconfig/buildout.cfg
...@@ -22,9 +23,12 @@ min_version = 8 ...@@ -22,9 +23,12 @@ min_version = 8
[trafficserver] [trafficserver]
recipe = slapos.recipe.cmmi recipe = slapos.recipe.cmmi
url = http://apache.claz.org/trafficserver/trafficserver-8.1.0.tar.bz2 url = http://apache.claz.org/trafficserver/trafficserver-8.1.1.tar.bz2
md5sum = 99bfeb61095e55cb151ef58d884cb3f1 md5sum = 4f4d1e7de19c77157be0c2a825b31026
shared = true shared = true
patch-options = -p1
patches =
${:_profile_base_location_}/trafficserver-8.1-stale-negative-cache-not-returnable.patch#e1a2f8a23f00cee1301ccf1a84e46763
configure-options = configure-options =
--with-openssl=${openssl:location} --with-openssl=${openssl:location}
--with-pcre=${pcre:location} --with-pcre=${pcre:location}
...@@ -37,7 +41,7 @@ configure-options = ...@@ -37,7 +41,7 @@ configure-options =
--enable-experimental-plugins --enable-experimental-plugins
--disable-posix-cap --disable-posix-cap
environment = environment =
PATH=${libtool:location}/bin:${make:location}/bin:${perl:location}/bin:${pkgconfig:location}/bin:%(PATH)s PATH=${libtool:location}/bin:${make:location}/bin:${patch:location}/bin:${perl:location}/bin:${pkgconfig:location}/bin:%(PATH)s
LDFLAGS =-L${openssl:location}/lib -Wl,-rpath=${openssl:location}/lib -L${tcl:location}/lib -Wl,-rpath=${tcl:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib LDFLAGS =-L${openssl:location}/lib -Wl,-rpath=${openssl:location}/lib -L${tcl:location}/lib -Wl,-rpath=${tcl:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
make-target = make-target =
......
--- trafficserver-8.1.1/proxy/http/HttpTransact.cc.orig 2020-12-01 00:30:26.000000000 +0100
+++ trafficserver-8.1.1/proxy/http/HttpTransact.cc 2021-01-11 11:35:41.946893735 +0100
@@ -5752,6 +5752,7 @@
HttpTransact::is_stale_cache_response_returnable(State *s)
{
HTTPHdr *cached_response = s->cache_info.object_read->response_get();
+ HTTPStatus cache_response_code = cached_response->status_get();
// First check if client allows cached response
// Note does_client_permit_lookup was set to
@@ -5760,6 +5761,12 @@
if (!s->cache_info.directives.does_client_permit_lookup) {
return false;
}
+ // We don't serve stale negative cache.
+ if (cache_response_code == HTTP_STATUS_INTERNAL_SERVER_ERROR || cache_response_code == HTTP_STATUS_GATEWAY_TIMEOUT ||
+ cache_response_code == HTTP_STATUS_BAD_GATEWAY || cache_response_code == HTTP_STATUS_SERVICE_UNAVAILABLE) {
+ TxnDebug("http_trans", "[is_stale_cache_response_returnable] stale negative cache");
+ return false;
+ }
// Spec says that we can not serve a stale document with a
// "must-revalidate header"
// How about "s-maxage" and "no-cache" directives?
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
recipe = slapos.recipe.cmmi recipe = slapos.recipe.cmmi
shared = true shared = true
url = https://lab.nexedi.com/nexedi/userhosts/repository/${:revision}/archive.tar.gz url = https://lab.nexedi.com/nexedi/userhosts/repository/${:revision}/archive.tar.gz
revision = 1d3b463e7856db6e674a06258c0840206e6a7b72 revision = a05fe5a3a5cb7005351ef4ec41460089f3ce4d0a
md5sum = 5a80b4d962d975f290a60cf790c3334d
configure-command = true configure-command = true
make-options = PREFIX=@@LOCATION@@ make-options = PREFIX=@@LOCATION@@
make-targets = check install make-targets = check install
...@@ -10,19 +10,10 @@ parts = ...@@ -10,19 +10,10 @@ parts =
wendelin.core wendelin.core
# wendelin.core installed from released egg from pypi # wendelin.core is installed from git checkout
[wendelin.core] [wendelin.core]
recipe = zc.recipe.egg:custom
<= wendelin.core-eggcommon
# wendelin.core installed from latest git version
[wendelin.core-dev]
recipe = zc.recipe.egg:develop recipe = zc.recipe.egg:develop
setup = ${wendelin.core-repository:location} setup = ${wendelin.core-repository:location}
<= wendelin.core-eggcommon
# common parts in between wendelin.core and wendelin.core-dev
[wendelin.core-eggcommon]
egg = wendelin.core egg = wendelin.core
setup-eggs = setup-eggs =
${pygolang:egg}[pyx.build] ${pygolang:egg}[pyx.build]
...@@ -41,6 +32,8 @@ PATH = ${git:location}/bin:%(PATH)s ...@@ -41,6 +32,8 @@ PATH = ${git:location}/bin:%(PATH)s
[wendelin.core-repository] [wendelin.core-repository]
recipe = slapos.recipe.build:gitclone recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/wendelin.core.git repository = https://lab.nexedi.com/nexedi/wendelin.core.git
# dir is pretty name as top-level -dev recipe branch = master
location = ${buildout:parts-directory}/wendelin.core-dev revision = v0.13-0-gb26ba55
# dir is pretty name as top-level recipe
location = ${buildout:parts-directory}/wendelin.core
git-executable = ${git:location}/bin/git git-executable = ${git:location}/bin/git
...@@ -15,7 +15,7 @@ parts = ...@@ -15,7 +15,7 @@ parts =
# keep neoppod first and in parts so that ZODB is built correctly # keep neoppod first and in parts so that ZODB is built correctly
neoppod neoppod
wendelin.core-dev wendelin.core
# for instance # for instance
wendelin.core-python wendelin.core-python
......
...@@ -7,7 +7,7 @@ set up. ...@@ -7,7 +7,7 @@ set up.
How to Use generic_varnish ? How to Use generic_varnish ?
============================ ============================
On slap console, you can instanciate varnish like this:: On slap console, you can instantiate varnish like this::
instance = request( instance = request(
software_type='varnish', software_type='varnish',
......
...@@ -48,5 +48,4 @@ gitdb = 0.6.4 ...@@ -48,5 +48,4 @@ gitdb = 0.6.4
pycrypto = 2.6.1 pycrypto = 2.6.1
pycurl = 7.43.0 pycurl = 7.43.0
slapos.recipe.download = 1.0 slapos.recipe.download = 1.0
slapos.recipe.template = 4.4
smmap = 0.9.0 smmap = 0.9.0
...@@ -84,5 +84,4 @@ numpy = 1.16.4 ...@@ -84,5 +84,4 @@ numpy = 1.16.4
# websockify 0.4.1 doesn't install well # websockify 0.4.1 doesn't install well
websockify = 0.3.0 websockify = 0.3.0
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 2.4.2
z3c.recipe.mkdir = 0.5 z3c.recipe.mkdir = 0.5
...@@ -105,5 +105,4 @@ mode = 0644 ...@@ -105,5 +105,4 @@ mode = 0644
rdiff-backup = 1.0.5+SlapOSPatched001 rdiff-backup = 1.0.5+SlapOSPatched001
gunicorn = 19.1.1 gunicorn = 19.1.1
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 2.4.3
PyRSS2Gen = 1.1 PyRSS2Gen = 1.1
...@@ -82,6 +82,3 @@ packages += ...@@ -82,6 +82,3 @@ packages +=
dh-autoreconf pkg-config doxygen maven xmlto dh-autoreconf pkg-config doxygen maven xmlto
# hellorina (shouldn't parts like lxml-python depend on the python of the SR?) # hellorina (shouldn't parts like lxml-python depend on the python of the SR?)
python-dev python-dev
[versions]
slapos.recipe.template = 4.4
...@@ -59,6 +59,3 @@ template = ...@@ -59,6 +59,3 @@ template =
key slapos_buildout slapos.buildout-repository:location key slapos_buildout slapos.buildout-repository:location
key temp_directory directory:tmp key temp_directory directory:tmp
raw runTestSuite_py ${buildout:bin-directory}/${runTestSuite_py:interpreter} raw runTestSuite_py ${buildout:bin-directory}/${runTestSuite_py:interpreter}
[versions]
slapos.recipe.template = 4.4
...@@ -26,7 +26,7 @@ md5sum = e8db3179e3278c6390a786cdcc947173 ...@@ -26,7 +26,7 @@ md5sum = e8db3179e3278c6390a786cdcc947173
[profile-caddy-replicate] [profile-caddy-replicate]
filename = instance-apache-replicate.cfg.in filename = instance-apache-replicate.cfg.in
md5sum = b29a4764dd489030030a72770162c157 md5sum = 2329022227099971a57f710832509153
[profile-slave-list] [profile-slave-list]
_update_hash_filename_ = templates/apache-custom-slave-list.cfg.in _update_hash_filename_ = templates/apache-custom-slave-list.cfg.in
...@@ -46,7 +46,7 @@ md5sum = 88af61e7abbf30dc99a1a2526161128d ...@@ -46,7 +46,7 @@ md5sum = 88af61e7abbf30dc99a1a2526161128d
[template-default-slave-virtualhost] [template-default-slave-virtualhost]
_update_hash_filename_ = templates/default-virtualhost.conf.in _update_hash_filename_ = templates/default-virtualhost.conf.in
md5sum = 266f175dbdfc588af7a86b0b1884fe73 md5sum = bd9e269130bac989faa639e0903814e2
[template-backend-haproxy-configuration] [template-backend-haproxy-configuration]
_update_hash_filename_ = templates/backend-haproxy.cfg.in _update_hash_filename_ = templates/backend-haproxy.cfg.in
...@@ -62,7 +62,7 @@ md5sum = 975177dedf677d24e14cede5d13187ce ...@@ -62,7 +62,7 @@ md5sum = 975177dedf677d24e14cede5d13187ce
[template-trafficserver-records-config] [template-trafficserver-records-config]
_update_hash_filename_ = templates/trafficserver/records.config.jinja2 _update_hash_filename_ = templates/trafficserver/records.config.jinja2
md5sum = 18076ae37306aca1f6ef11e2173c887f md5sum = b99403e02d1aff471a7d5ebd0afbdb6c
[template-trafficserver-storage-config] [template-trafficserver-storage-config]
_update_hash_filename_ = templates/trafficserver/storage.config.jinja2 _update_hash_filename_ = templates/trafficserver/storage.config.jinja2
......
...@@ -111,7 +111,6 @@ context = ...@@ -111,7 +111,6 @@ context =
{% set authorized_slave_string_list = [] %} {% set authorized_slave_string_list = [] %}
{% set authorized_slave_list = [] %} {% set authorized_slave_list = [] %}
{% set rejected_slave_dict = {} %} {% set rejected_slave_dict = {} %}
{% set rejected_slave_title_dict = {} %}
{% set warning_slave_dict = {} %} {% set warning_slave_dict = {} %}
{% set used_host_list = [] %} {% set used_host_list = [] %}
{% for slave in sorted(instance_parameter_dict['slave-instance-list']) %} {% for slave in sorted(instance_parameter_dict['slave-instance-list']) %}
...@@ -247,7 +246,6 @@ context = ...@@ -247,7 +246,6 @@ context =
{% do authorized_slave_list.append(authorized_slave) %} {% do authorized_slave_list.append(authorized_slave) %}
{% else %} {% else %}
{% do rejected_slave_dict.__setitem__(slave.get('slave_reference'), sorted(slave_error_list)) %} {% do rejected_slave_dict.__setitem__(slave.get('slave_reference'), sorted(slave_error_list)) %}
{% do rejected_slave_title_dict.__setitem__(slave.get('slave_title'), sorted(slave_error_list)) %}
{% endif %} {% endif %}
{% if len(slave_warning_list) > 0 %} {% if len(slave_warning_list) > 0 %}
{% do warning_slave_dict.__setitem__(slave.get('slave_reference'), sorted(slave_warning_list)) %} {% do warning_slave_dict.__setitem__(slave.get('slave_reference'), sorted(slave_warning_list)) %}
...@@ -326,7 +324,7 @@ accepted-slave-amount = {{ authorized_slave_list | length }} ...@@ -326,7 +324,7 @@ accepted-slave-amount = {{ authorized_slave_list | length }}
rejected-slave-amount = {{ rejected_slave_dict | length }} rejected-slave-amount = {{ rejected_slave_dict | length }}
backend-client-caucase-url = {{ caucase_url }} backend-client-caucase-url = {{ caucase_url }}
{# sort_keys are important in order to avoid shuffling parameters on each run #} {# sort_keys are important in order to avoid shuffling parameters on each run #}
rejected-slave-dict = {{ dumps(json_module.dumps(rejected_slave_title_dict, sort_keys=True)) }} rejected-slave-dict = {{ dumps(json_module.dumps(rejected_slave_dict, sort_keys=True)) }}
rejected-slave-promise-url = ${rejected-slave-promise:config-url} rejected-slave-promise-url = ${rejected-slave-promise:config-url}
master-key-upload-url = ${request-kedifa:connection-master-key-upload-url} master-key-upload-url = ${request-kedifa:connection-master-key-upload-url}
master-key-generate-auth-url = ${request-kedifa:connection-master-key-generate-auth-url} master-key-generate-auth-url = ${request-kedifa:connection-master-key-generate-auth-url}
...@@ -485,6 +483,7 @@ user-ca-certificate = ${directory:aikc}/user-ca-certificate.pem ...@@ -485,6 +483,7 @@ user-ca-certificate = ${directory:aikc}/user-ca-certificate.pem
user-crl = ${directory:aikc}/user-crl.pem user-crl = ${directory:aikc}/user-crl.pem
user-created = ${directory:aikc}/user-created user-created = ${directory:aikc}/user-created
csr_id = ${directory:aikc}/csr_id csr_id = ${directory:aikc}/csr_id
data_dir = ${directory:aikc}/caucase-updater
[aikc-user-csr] [aikc-user-csr]
recipe = plone.recipe.command recipe = plone.recipe.command
...@@ -547,7 +546,7 @@ command = ...@@ -547,7 +546,7 @@ command =
buildout_bin_directory=software_parameter_dict['bin_directory'], buildout_bin_directory=software_parameter_dict['bin_directory'],
updater_path='${directory:service}/aikc-user-caucase-updater', updater_path='${directory:service}/aikc-user-caucase-updater',
url='${aikc-config:caucase-url}', url='${aikc-config:caucase-url}',
data_dir='${directory:srv}/caucase-updater', data_dir='${aikc-config:data_dir}',
crt_path='${aikc-config:key}', crt_path='${aikc-config:key}',
ca_path='${aikc-config:user-ca-certificate}', ca_path='${aikc-config:user-ca-certificate}',
crl_path='${aikc-config:user-crl}', crl_path='${aikc-config:user-crl}',
...@@ -620,6 +619,7 @@ user-ca-certificate = ${directory:aibcc}/user-ca-certificate.pem ...@@ -620,6 +619,7 @@ user-ca-certificate = ${directory:aibcc}/user-ca-certificate.pem
user-crl = ${directory:aibcc}/user-crl.pem user-crl = ${directory:aibcc}/user-crl.pem
user-created = ${directory:aibcc}/user-created user-created = ${directory:aibcc}/user-created
csr_id = ${directory:aibcc}/csr_id csr_id = ${directory:aibcc}/csr_id
data_dir = ${directory:aibcc}/caucase-updater
[aibcc-user-csr] [aibcc-user-csr]
recipe = plone.recipe.command recipe = plone.recipe.command
...@@ -684,7 +684,7 @@ command = ...@@ -684,7 +684,7 @@ command =
buildout_bin_directory=software_parameter_dict['bin_directory'], buildout_bin_directory=software_parameter_dict['bin_directory'],
updater_path='${directory:service}/aibcc-user-caucase-updater', updater_path='${directory:service}/aibcc-user-caucase-updater',
url='${aibcc-config:caucase-url}', url='${aibcc-config:caucase-url}',
data_dir='${directory:srv}/caucase-updater', data_dir='${aibcc-config:data_dir}',
crt_path='${aibcc-config:key}', crt_path='${aibcc-config:key}',
ca_path='${aibcc-config:user-ca-certificate}', ca_path='${aibcc-config:user-ca-certificate}',
crl_path='${aibcc-config:user-crl}', crl_path='${aibcc-config:user-crl}',
...@@ -747,9 +747,9 @@ filename = rejected-slave.json ...@@ -747,9 +747,9 @@ filename = rejected-slave.json
directory = ${directory:promise-output} directory = ${directory:promise-output}
rendered = ${:directory}/${:filename} rendered = ${:directory}/${:filename}
template = {{ software_parameter_dict['template_empty'] }} template = {{ software_parameter_dict['template_empty'] }}
{% if rejected_slave_title_dict %} {% if rejected_slave_dict %}
{# sort_keys are important in order to avoid shuffling parameters on each run #} {# sort_keys are important in order to avoid shuffling parameters on each run #}
content = {{ dumps(json_module.dumps(rejected_slave_title_dict, indent=2, sort_keys=True)) }} content = {{ dumps(json_module.dumps(rejected_slave_dict, indent=2, sort_keys=True)) }}
{% else %} {% else %}
content = content =
{% endif %} {% endif %}
......
...@@ -246,7 +246,6 @@ gitdb = 0.6.4 ...@@ -246,7 +246,6 @@ gitdb = 0.6.4
plone.recipe.command = 1.1 plone.recipe.command = 1.1
pycrypto = 2.6.1 pycrypto = 2.6.1
rdiff-backup = 1.0.5+SlapOSPatched001 rdiff-backup = 1.0.5+SlapOSPatched001
slapos.recipe.template = 4.4
smmap = 0.9.0 smmap = 0.9.0
websockify = 0.8.0 websockify = 0.8.0
......
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
timeout {{ slave_parameter['request-timeout'] }}s timeout {{ slave_parameter['request-timeout'] }}s
# force reset of X-Forwarded-For # force reset of X-Forwarded-For
header_upstream X-Forwarded-For {remote} header_upstream X-Forwarded-For {remote}
# workaround for lost connection to haproxy by reconnecting
try_duration 3s
try_interval 250ms
{%- endmacro %} {# proxy_header #} {%- endmacro %} {# proxy_header #}
{%- for tls in [True, False] %} {%- for tls in [True, False] %}
......
...@@ -23,9 +23,19 @@ CONFIG proxy.config.log.logfile_dir STRING {{ ats_directory['log'] }} ...@@ -23,9 +23,19 @@ CONFIG proxy.config.log.logfile_dir STRING {{ ats_directory['log'] }}
# Implement RFC 5861 with core # Implement RFC 5861 with core
CONFIG proxy.config.http.cache.open_write_fail_action INT 2 CONFIG proxy.config.http.cache.open_write_fail_action INT 2
CONFIG proxy.config.body_factory.template_sets_dir STRING {{ ats_configuration['templates-dir'] }} CONFIG proxy.config.body_factory.template_sets_dir STRING {{ ats_configuration['templates-dir'] }}
# Support stale-if-error by returning cached content on backend 5xx or unavailability # Simulate stale-if-error (not supported by TrafficServer), by using internal
# mechanism
# This results with replying last know non-5xx response until max_stale_age is reached
# ignoring max-age returned by the server
CONFIG proxy.config.http.negative_revalidating_enabled INT 1 CONFIG proxy.config.http.negative_revalidating_enabled INT 1
CONFIG proxy.config.http.negative_revalidating_lifetime INT 86400 # max_stale_age set here means that for 1 week since last correct response
# the response will be sent by the system
CONFIG proxy.config.http.cache.max_stale_age INT 604800
# negative_revalidating_lifetime just adds Expires header calculated as
# Expires = Date + negative_revalidating_lifetime
# for case when backend replies 5xx, and Age > max-age and Age < max_stale_age
# and that's not needed, so drop this behaviour
CONFIG proxy.config.http.negative_revalidating_lifetime INT 0
############################################################################## ##############################################################################
# Thread configurations. Docs: # Thread configurations. Docs:
...@@ -80,10 +90,9 @@ CONFIG proxy.config.net.default_inactivity_timeout INT 86400 ...@@ -80,10 +90,9 @@ CONFIG proxy.config.net.default_inactivity_timeout INT 86400
# Origin server connect attempts. Docs: # Origin server connect attempts. Docs:
# https://docs.trafficserver.apache.org/records.config#origin-server-connect-attempts # https://docs.trafficserver.apache.org/records.config#origin-server-connect-attempts
############################################################################## ##############################################################################
# Try only once to connect (do not retry) # workaround for lost connection to haproxy by reconnecting
CONFIG proxy.config.http.connect_attempts_max_retries INT 0 CONFIG proxy.config.http.connect_attempts_max_retries INT 3
# Try only once with server marked dead (do not retry) CONFIG proxy.config.http.connect_attempts_max_retries_dead_server INT 1
CONFIG proxy.config.http.connect_attempts_max_retries_dead_server INT 0
CONFIG proxy.config.http.connect_attempts_rr_retries INT 3 CONFIG proxy.config.http.connect_attempts_rr_retries INT 3
CONFIG proxy.config.http.connect_attempts_timeout INT {{ ats_configuration['request-timeout'] }} CONFIG proxy.config.http.connect_attempts_timeout INT {{ ats_configuration['request-timeout'] }}
CONFIG proxy.config.http.post_connect_attempts_timeout INT {{ ats_configuration['request-timeout'] }} CONFIG proxy.config.http.post_connect_attempts_timeout INT {{ ats_configuration['request-timeout'] }}
......
...@@ -49,6 +49,7 @@ import xml.etree.ElementTree as ET ...@@ -49,6 +49,7 @@ import xml.etree.ElementTree as ET
import urlparse import urlparse
import socket import socket
import sys import sys
import logging
try: try:
...@@ -100,7 +101,6 @@ def new_getaddrinfo(*args): ...@@ -100,7 +101,6 @@ def new_getaddrinfo(*args):
# for development: debugging logs and install Ctrl+C handler # for development: debugging logs and install Ctrl+C handler
if os.environ.get('SLAPOS_TEST_DEBUG'): if os.environ.get('SLAPOS_TEST_DEBUG'):
import logging
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
import unittest import unittest
unittest.installHandler() unittest.installHandler()
...@@ -111,6 +111,29 @@ def der2pem(der): ...@@ -111,6 +111,29 @@ def der2pem(der):
return certificate.public_bytes(serialization.Encoding.PEM) return certificate.public_bytes(serialization.Encoding.PEM)
# comes from https://stackoverflow.com/a/21788372/9256748
def patch_broken_pipe_error():
"""Monkey Patch BaseServer.handle_error to not write
a stacktrace to stderr on broken pipe.
https://stackoverflow.com/a/7913160"""
from SocketServer import BaseServer
handle_error = BaseServer.handle_error
def my_handle_error(self, request, client_address):
type, err, tb = sys.exc_info()
# there might be better ways to detect the specific erro
if repr(err) == "error(32, 'Broken pipe')":
pass
else:
handle_error(self, request, client_address)
BaseServer.handle_error = my_handle_error
patch_broken_pipe_error()
def createKey(): def createKey():
key = rsa.generate_private_key( key = rsa.generate_private_key(
public_exponent=65537, key_size=2048, backend=default_backend()) public_exponent=65537, key_size=2048, backend=default_backend())
...@@ -430,15 +453,79 @@ def fakeHTTPResult(domain, real_ip, path, port=HTTP_PORT, ...@@ -430,15 +453,79 @@ def fakeHTTPResult(domain, real_ip, path, port=HTTP_PORT,
class TestHandler(BaseHTTPRequestHandler): class TestHandler(BaseHTTPRequestHandler):
identification = None identification = None
configuration = {}
def do_DELETE(self):
config = self.configuration.pop(self.path, None)
if config is None:
self.send_response(204)
self.end_headers()
else:
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({self.path: config}, indent=2))
def do_PUT(self):
config = {
'status_code': self.headers.dict.get('status-code', '200')
}
prefix = 'x-reply-header-'
length = len(prefix)
for key, value in self.headers.dict.items():
if key.startswith(prefix):
header = '-'.join([q.capitalize() for q in key[length:].split('-')])
config[header] = value.strip()
if 'x-reply-body' in self.headers.dict:
config['Body'] = base64.b64decode(self.headers.dict['x-reply-body'])
self.configuration[self.path] = config
self.send_response(201)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({self.path: config}, indent=2))
def do_POST(self): def do_POST(self):
return self.do_GET() return self.do_GET()
def do_GET(self): def do_GET(self):
timeout = int(self.headers.dict.get('timeout', '0')) config = self.configuration.get(self.path, None)
compress = int(self.headers.dict.get('compress', '0')) if config is not None:
config = config.copy()
response = config.pop('Body', None)
status_code = int(config.pop('status_code'))
timeout = int(config.pop('Timeout', '0'))
compress = int(config.pop('Compress', '0'))
header_dict = config
else:
response = None
status_code = 200
timeout = int(self.headers.dict.get('timeout', '0'))
compress = int(self.headers.dict.get('compress', '0'))
header_dict = {}
prefix = 'x-reply-header-'
length = len(prefix)
for key, value in self.headers.dict.items():
if key.startswith(prefix):
header = '-'.join([q.capitalize() for q in key[length:].split('-')])
header_dict[header] = value.strip()
if response is None:
if 'x-reply-body' not in self.headers.dict:
response = {
'Path': self.path,
'Incoming Headers': self.headers.dict
}
response = json.dumps(response, indent=2)
else:
response = base64.b64decode(self.headers.dict['x-reply-body'])
time.sleep(timeout) time.sleep(timeout)
self.send_response(200) self.send_response(status_code)
for key, value in header_dict.items():
self.send_header(key, value)
if self.identification is not None: if self.identification is not None:
self.send_header('X-Backend-Identification', self.identification) self.send_header('X-Backend-Identification', self.identification)
...@@ -446,29 +533,12 @@ class TestHandler(BaseHTTPRequestHandler): ...@@ -446,29 +533,12 @@ class TestHandler(BaseHTTPRequestHandler):
drop_header_list = [] drop_header_list = []
for header in self.headers.dict.get('x-drop-header', '').split(): for header in self.headers.dict.get('x-drop-header', '').split():
drop_header_list.append(header) drop_header_list.append(header)
prefix = 'x-reply-header-'
length = len(prefix)
for key, value in self.headers.dict.items():
if key.startswith(prefix):
self.send_header(
'-'.join([q.capitalize() for q in key[length:].split('-')]),
value.strip()
)
if 'Content-Type' not in drop_header_list: if 'Content-Type' not in drop_header_list:
self.send_header("Content-Type", "application/json") self.send_header("Content-Type", "application/json")
if 'Set-Cookie' not in drop_header_list: if 'Set-Cookie' not in drop_header_list:
self.send_header('Set-Cookie', 'secured=value;secure') self.send_header('Set-Cookie', 'secured=value;secure')
self.send_header('Set-Cookie', 'nonsecured=value') self.send_header('Set-Cookie', 'nonsecured=value')
if 'x-reply-body' not in self.headers.dict:
response = {
'Path': self.path,
'Incoming Headers': self.headers.dict
}
response = json.dumps(response, indent=2)
else:
response = base64.b64decode(self.headers.dict['x-reply-body'])
if compress: if compress:
self.send_header('Content-Encoding', 'gzip') self.send_header('Content-Encoding', 'gzip')
out = StringIO.StringIO() out = StringIO.StringIO()
...@@ -3788,7 +3858,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -3788,7 +3858,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
self.assertNotEqual(via, None) self.assertNotEqual(via, None)
self.assertRegexpMatches( self.assertRegexpMatches(
via, via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.0\)$' r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.1\)$'
) )
def test_enable_cache_server_alias(self): def test_enable_cache_server_alias(self):
...@@ -3830,7 +3900,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -3830,7 +3900,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
self.assertNotEqual(via, None) self.assertNotEqual(via, None)
self.assertRegexpMatches( self.assertRegexpMatches(
via, via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.0\)$' r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.1\)$'
) )
result = fakeHTTPResult( result = fakeHTTPResult(
...@@ -3892,63 +3962,9 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -3892,63 +3962,9 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
self.assertNotEqual(via, None) self.assertNotEqual(via, None)
self.assertRegexpMatches( self.assertRegexpMatches(
via, via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.0\)$' r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.1\)$'
) )
# check stale-if-error support (assumes stale-while-revalidate is same)
# wait a bit for max-age to expire
time.sleep(2)
# real check: cache access provides old data, access cache directly, as
# caddy has to be stopped
try:
# stop the backend, to have error on while connecting to it
self.stopServerProcess()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600',
},
source_ip=source_ip
)
self.assertEqual(result.status_code, httplib.OK)
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
self.assertKeyWithPop('Expires', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
# ATS does not cache the cookied text content, see:
# https://docs.trafficserver.apache.org/en/7.1.x/admin-guide/\
# configuration/cache-basics.en.html#caching-cookied-objects
# 'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600',
},
headers
)
backend_headers = result.json()['Incoming Headers']
self.assertBackendHeaders(backend_headers, parameter_dict['domain'])
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.0\)$'
)
finally:
self.startServerProcess()
# END: check stale-if-error support
# BEGIN: Check that squid.log is correctly filled in # BEGIN: Check that squid.log is correctly filled in
ats_log_file_list = glob.glob( ats_log_file_list = glob.glob(
os.path.join( os.path.join(
...@@ -3959,33 +3975,211 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -3959,33 +3975,211 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
direct_pattern = re.compile( direct_pattern = re.compile(
r'.*TCP_MISS/200 .*test-path/deeper.*enablecache.example.com' r'.*TCP_MISS/200 .*test-path/deeper.*enablecache.example.com'
'.* - DIRECT*') '.* - DIRECT*')
refresh_pattern = re.compile(
r'.*TCP_REFRESH_MISS/200 .*test-path/deeper.*enablecache.example.com'
'.* - DIRECT*')
# ATS needs some time to flush logs # ATS needs some time to flush logs
timeout = 5 timeout = 5
b = time.time() b = time.time()
while True: while True:
direct_pattern_match = 0 direct_pattern_match = 0
refresh_pattern_match = 0
if (time.time() - b) > timeout: if (time.time() - b) > timeout:
break break
with open(ats_log_file) as fh: with open(ats_log_file) as fh:
for line in fh.readlines(): for line in fh.readlines():
if direct_pattern.match(line): if direct_pattern.match(line):
direct_pattern_match += 1 direct_pattern_match += 1
if refresh_pattern.match(line): if direct_pattern_match > 0:
refresh_pattern_match += 1
if direct_pattern_match > 0 and refresh_pattern_match:
break break
time.sleep(0.1) time.sleep(0.1)
with open(ats_log_file) as fh: with open(ats_log_file) as fh:
ats_log = fh.read() ats_log = fh.read()
self.assertRegexpMatches(ats_log, direct_pattern) self.assertRegexpMatches(ats_log, direct_pattern)
self.assertRegexpMatches(ats_log, refresh_pattern)
# END: Check that squid.log is correctly filled in # END: Check that squid.log is correctly filled in
def _hack_ats(self, max_stale_age):
records_config = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'trafficserver', 'records.config'
))
self.assertEqual(1, len(records_config))
self._hack_ats_records_config_path = records_config[0]
original_max_stale_age = \
'CONFIG proxy.config.http.cache.max_stale_age INT 604800\n'
new_max_stale_age = \
'CONFIG proxy.config.http.cache.max_stale_age INT %s\n' % (
max_stale_age,)
with open(self._hack_ats_records_config_path) as fh:
self._hack_ats_original_records_config = fh.readlines()
# sanity check - are we really do it?
self.assertIn(
original_max_stale_age,
self._hack_ats_original_records_config)
new_records_config = []
max_stale_age_changed = False
for line in self._hack_ats_original_records_config:
if line == original_max_stale_age:
line = new_max_stale_age
max_stale_age_changed = True
new_records_config.append(line)
self.assertTrue(max_stale_age_changed)
with open(self._hack_ats_records_config_path, 'w') as fh:
fh.write(''.join(new_records_config))
self._hack_ats_restart()
def _unhack_ats(self):
with open(self._hack_ats_records_config_path, 'w') as fh:
fh.write(''.join(self._hack_ats_original_records_config))
self._hack_ats_restart()
def _hack_ats_restart(self):
for process_info in self.callSupervisorMethod('getAllProcessInfo'):
if process_info['name'].startswith(
'trafficserver') and process_info['name'].endswith('-on-watch'):
self.callSupervisorMethod(
'stopProcess', '%(group)s:%(name)s' % process_info)
self.callSupervisorMethod(
'startProcess', '%(group)s:%(name)s' % process_info)
# give short time for the ATS to start back
time.sleep(5)
for process_info in self.callSupervisorMethod('getAllProcessInfo'):
if process_info['name'].startswith(
'trafficserver') and process_info['name'].endswith('-on-watch'):
self.assertEqual(process_info['statename'], 'RUNNING')
def test_enable_cache_negative_revalidate(self):
parameter_dict = self.assertSlaveBase('enable_cache')
source_ip = '127.0.0.1'
# have unique path for this test
path = self.id()
max_stale_age = 30
max_age = int(max_stale_age / 2.)
body_200 = b'Body 200'
body_502 = b'Body 502'
body_502_new = b'Body 502 new'
body_200_new = b'Body 200 new'
self.addCleanup(self._unhack_ats)
self._hack_ats(max_stale_age)
def configureResult(status_code, body):
backend_url = self.getSlaveParameterDictDict()['enable_cache']['url']
result = requests.put(backend_url + path, headers={
'X-Reply-Header-Cache-Control': 'max-age=%s, public' % (max_age,),
'Status-Code': status_code,
'X-Reply-Body': base64.b64encode(body),
})
self.assertEqual(result.status_code, httplib.CREATED)
def checkResult(status_code, body):
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], path,
source_ip=source_ip
)
self.assertEqual(result.status_code, status_code)
self.assertEqual(result.text, body)
self.assertNotIn('Expires', result.headers)
# backend returns something correctly
configureResult('200', body_200)
checkResult(httplib.OK, body_200)
configureResult('502', body_502)
time.sleep(1)
# even if backend returns 502, ATS gives cached result
checkResult(httplib.OK, body_200)
time.sleep(max_stale_age + 2)
# max_stale_age passed, time to return 502 from the backend
checkResult(httplib.BAD_GATEWAY, body_502)
configureResult('502', body_502_new)
time.sleep(1)
# even if there is new negative response on the backend, the old one is
# served from the cache
checkResult(httplib.BAD_GATEWAY, body_502)
time.sleep(max_age + 2)
# now as max-age of negative response passed, the new one is served
checkResult(httplib.BAD_GATEWAY, body_502_new)
configureResult('200', body_200_new)
time.sleep(1)
checkResult(httplib.BAD_GATEWAY, body_502_new)
time.sleep(max_age + 2)
# backend is back to normal, as soon as negative response max-age passed
# the new response is served
checkResult(httplib.OK, body_200_new)
@skip('Feature postponed')
def test_enable_cache_stale_if_error_respected(self):
parameter_dict = self.assertSlaveBase('enable_cache')
source_ip = '127.0.0.1'
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600',
},
source_ip=source_ip
)
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600'
},
headers
)
backend_headers = result.json()['Incoming Headers']
self.assertBackendHeaders(backend_headers, parameter_dict['domain'])
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.1\)$'
)
# check stale-if-error support is really respected if not present in the
# request
# wait a bit for max-age to expire
time.sleep(2)
# real check: cache access does not provide old data with stopped backend
try:
# stop the backend, to have error on while connecting to it
self.stopServerProcess()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1',
},
source_ip=source_ip
)
self.assertEqual(result.status_code, httplib.BAD_GATEWAY)
finally:
self.startServerProcess()
# END: check stale-if-error support
def test_enable_cache_ats_timeout(self): def test_enable_cache_ats_timeout(self):
parameter_dict = self.assertSlaveBase('enable_cache') parameter_dict = self.assertSlaveBase('enable_cache')
# check that timeout seen by ATS does not result in many queries done # check that timeout seen by ATS does not result in many queries done
...@@ -4105,7 +4299,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -4105,7 +4299,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
self.assertNotEqual(via, None) self.assertNotEqual(via, None)
self.assertRegexpMatches( self.assertRegexpMatches(
via, via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.0\)$' r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.1\)$'
) )
try: try:
...@@ -4152,7 +4346,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -4152,7 +4346,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
self.assertNotEqual(via, None) self.assertNotEqual(via, None)
self.assertRegexpMatches( self.assertRegexpMatches(
via, via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.0\)$' r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/8.1.1\)$'
) )
def test_enable_http2_false(self): def test_enable_http2_false(self):
......
...@@ -24,6 +24,3 @@ context = ...@@ -24,6 +24,3 @@ context =
key eggs_directory buildout:eggs-directory key eggs_directory buildout:eggs-directory
key caucase_jinja2_library caucase-jinja2-library:target key caucase_jinja2_library caucase-jinja2-library:target
key instance_caucased instance-caucased:target key instance_caucased instance-caucased:target
[versions]
slapos.recipe.template = 3.0
...@@ -39,4 +39,3 @@ eggs = ...@@ -39,4 +39,3 @@ eggs =
cns.recipe.symlink = 0.2.3 cns.recipe.symlink = 0.2.3
collective.recipe.environment = 0.2.0 collective.recipe.environment = 0.2.0
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 4.4
[instance.cfg]
filename = instance.cfg.in
md5sum = a24384487467a07e827edab17a0b7206
[runTestSuite.in]
_update_hash_filename_ = runTestSuite.in
md5sum = 21a8a202b14475707c414056ba393b3d
[buildout]
parts =
publish-env-path
runTestSuite
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
[publish-env-path]
recipe = slapos.cookbook:publish
readme = Source the script to set up the environment.
script = ${cythonplus_env.sh:rendered}
repository = ${cythonplus-repository:repository}
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
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}
[directory]
recipe = slapos.cookbook:mkdirectory
bin = $${buildout:directory}/bin
tmp = $${buildout:directory}/tmp
[cythonplus-repository]
recipe = slapos.recipe.build:gitclone
repository = ${cythonplus-repository:location}
git-executable = ${git:location}/bin/git
shared = true
[runTestSuite]
recipe = slapos.recipe.template:jinja2
rendered = $${directory:bin}/$${:_buildout_section_name_}
template = ${runTestSuite.in:target}
mode = 0755
context =
key tmpdir directory:tmp
key slapparameter_dict slap-configuration:configuration
key cythonplus_repository cythonplus-repository:location
raw runTestSuite_interpreter ${runTestSuite_interpreter:bin-directory}/${runTestSuite_interpreter:interpreter}
raw cythonplus_env_sh ${cythonplus_env.sh:rendered}
#!{{ runTestSuite_py }} #!{{ runTestSuite_interpreter }}
""" """
Script to run the Cython test suite using Nexedi's test node framework. Script to run the Cython test suite using Nexedi's test node framework.
""" """
...@@ -9,7 +9,7 @@ from erp5.util import taskdistribution, testsuite ...@@ -9,7 +9,7 @@ from erp5.util import taskdistribution, testsuite
os.environ['TEMP'] = {{ repr(tmpdir) }} os.environ['TEMP'] = {{ repr(tmpdir) }}
command = """. {{ cython_env_sh }} command = """. {{ cythonplus_env_sh }}
make all test make all test
""" """
...@@ -96,7 +96,7 @@ def main(): ...@@ -96,7 +96,7 @@ def main():
with open(os.devnull) as stdin: with open(os.devnull) as stdin:
p = subprocess.Popen(command, shell=True, stdin=stdin, p = subprocess.Popen(command, shell=True, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
cwd={{repr(cython_repository)}}) cwd={{ repr(cythonplus_repository) }})
except Exception: except Exception:
end = time() end = time()
stderr = traceback.format_exc() stderr = traceback.format_exc()
......
[buildout]
extends =
buildout.hash.cfg
../../stack/slapos.cfg
../../component/cythonplus/buildout.cfg
parts =
slapos-cookbook
instance.cfg
[instance.cfg]
recipe = slapos.recipe.template
output = ${buildout:directory}/${:_buildout_section_name_}
url = ${:_profile_base_location_}/${:filename}
[runTestSuite.in]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_update_hash_filename_}
[runTestSuite_interpreter]
recipe = zc.recipe.egg
eggs = erp5.util
interpreter = ${:_buildout_section_name_}
...@@ -34,4 +34,3 @@ command = ...@@ -34,4 +34,3 @@ command =
[versions] [versions]
openssl = 1.0.1c openssl = 1.0.1c
slapos.recipe.template = 2.4.2
...@@ -34,4 +34,3 @@ command = ...@@ -34,4 +34,3 @@ command =
[versions] [versions]
openssl = 1.0.1c openssl = 1.0.1c
slapos.recipe.template = 2.4.2
...@@ -49,7 +49,6 @@ mysqlclient = 1.3.12 ...@@ -49,7 +49,6 @@ mysqlclient = 1.3.12
# indirect dependancies # indirect dependancies
cp.recipe.cmd = 0.5 cp.recipe.cmd = 0.5
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 4.4
zope.exceptions = 4.0.7 zope.exceptions = 4.0.7
zope.testing = 4.1.3 zope.testing = 4.1.3
zc.recipe.testrunner = 2.0.0 zc.recipe.testrunner = 2.0.0
......
...@@ -59,7 +59,7 @@ Setting up replication ...@@ -59,7 +59,7 @@ Setting up replication
In addition to your usual parameter set, you needs to provide the following parameters:: In addition to your usual parameter set, you needs to provide the following parameters::
{ {
"zope-partition-dict": {}, So no zope is instanciated "zope-partition-dict": {}, So no zope is instantiated
"zodb": [ "zodb": [
{ {
"storage-dict": { "storage-dict": {
......
...@@ -48,10 +48,6 @@ def setUpModule(): ...@@ -48,10 +48,6 @@ def setUpModule():
class ERP5InstanceTestCase(SlapOSInstanceTestCase): class ERP5InstanceTestCase(SlapOSInstanceTestCase):
"""ERP5 base test case """ERP5 base test case
""" """
# ERP5 instanciation needs to run several times before being ready, as
# the root instance request more instances.
instance_max_retry = 7 # XXX how many times ?
def getRootPartitionConnectionParameterDict(self): def getRootPartitionConnectionParameterDict(self):
"""Return the output paramters from the root partition""" """Return the output paramters from the root partition"""
return json.loads( return json.loads(
......
...@@ -50,7 +50,31 @@ class EchoHTTPServer(ManagedHTTPServer): ...@@ -50,7 +50,31 @@ class EchoHTTPServer(ManagedHTTPServer):
self.end_headers() self.end_headers()
self.wfile.write(response) self.wfile.write(response)
log_message = logging.getLogger(__name__ + '.HeaderEchoHandler').info log_message = logging.getLogger(__name__ + '.EchoHTTPServer').info
class EchoHTTP11Server(ManagedHTTPServer):
"""An HTTP/1.1 Server responding with the request path and incoming headers,
encoded in json.
"""
class RequestHandler(BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.1'
def do_GET(self):
# type: () -> None
self.send_response(200)
self.send_header("Content-Type", "application/json")
response = json.dumps(
{
'Path': self.path,
'Incoming Headers': self.headers.dict
},
indent=2,
)
self.send_header("Content-Length", len(response))
self.end_headers()
self.wfile.write(response)
log_message = logging.getLogger(__name__ + '.EchoHTTP11Server').info
class CaucaseService(ManagedResource): class CaucaseService(ManagedResource):
...@@ -105,6 +129,7 @@ class CaucaseService(ManagedResource): ...@@ -105,6 +129,7 @@ class CaucaseService(ManagedResource):
shutil.rmtree(self.directory) shutil.rmtree(self.directory)
class BalancerTestCase(ERP5InstanceTestCase): class BalancerTestCase(ERP5InstanceTestCase):
@classmethod @classmethod
...@@ -147,14 +172,14 @@ class BalancerTestCase(ERP5InstanceTestCase): ...@@ -147,14 +172,14 @@ class BalancerTestCase(ERP5InstanceTestCase):
class SlowHTTPServer(ManagedHTTPServer): class SlowHTTPServer(ManagedHTTPServer):
"""An HTTP Server which reply after 3 seconds. """An HTTP Server which reply after 2 seconds.
""" """
class RequestHandler(BaseHTTPRequestHandler): class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self): def do_GET(self):
# type: () -> None # type: () -> None
self.send_response(200) self.send_response(200)
self.send_header("Content-Type", "text/plain") self.send_header("Content-Type", "text/plain")
time.sleep(3) time.sleep(2)
self.end_headers() self.end_headers()
self.wfile.write("OK\n") self.wfile.write("OK\n")
...@@ -179,12 +204,13 @@ class TestAccessLog(BalancerTestCase, CrontabMixin): ...@@ -179,12 +204,13 @@ class TestAccessLog(BalancerTestCase, CrontabMixin):
urlparse.urljoin(self.default_balancer_url, '/url_path'), urlparse.urljoin(self.default_balancer_url, '/url_path'),
verify=False, verify=False,
) )
time.sleep(.5) # wait a bit more until access is logged
with open(os.path.join(self.computer_partition_root_path, 'var', 'log', 'apache-access.log')) as access_log_file: with open(os.path.join(self.computer_partition_root_path, 'var', 'log', 'apache-access.log')) as access_log_file:
access_line = access_log_file.read() access_line = access_log_file.read().splitlines()[-1]
self.assertIn('/url_path', access_line) self.assertIn('/url_path', access_line)
# last \d is the request time in micro seconds, since this SlowHTTPServer # last \d is the request time in milli seconds, since this SlowHTTPServer
# sleeps for 3 seconds, it should take between 3 and 4 seconds to process # sleeps for 2 seconds, it should take between 2 and 3 seconds to process
# the request - but our test machines can be slow sometimes, so we tolerate # the request - but our test machines can be slow sometimes, so we tolerate
# it can take up to 20 seconds. # it can take up to 20 seconds.
match = re.match( match = re.match(
...@@ -194,8 +220,8 @@ class TestAccessLog(BalancerTestCase, CrontabMixin): ...@@ -194,8 +220,8 @@ class TestAccessLog(BalancerTestCase, CrontabMixin):
self.assertTrue(match) self.assertTrue(match)
assert match assert match
request_time = int(match.groups()[-1]) request_time = int(match.groups()[-1])
self.assertGreater(request_time, 3 * 1000 * 1000) self.assertGreater(request_time, 2 * 1000)
self.assertLess(request_time, 20 * 1000 * 1000) self.assertLess(request_time, 20 * 1000)
def test_access_log_apachedex_report(self): def test_access_log_apachedex_report(self):
# type: () -> None # type: () -> None
...@@ -334,17 +360,132 @@ class TestBalancer(BalancerTestCase): ...@@ -334,17 +360,132 @@ class TestBalancer(BalancerTestCase):
requests.get(self.default_balancer_url, verify=False, cookies=cookies).text, requests.get(self.default_balancer_url, verify=False, cookies=cookies).text,
'backend_web_server1') 'backend_web_server1')
def test_balancer_stats_socket(self):
# real time statistics can be obtained by using the stats socket and there
# is a wrapper which makes this a bit easier.
socat_process = subprocess.Popen(
[self.computer_partition_root_path + '/bin/haproxy-socat-stats'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
try:
output, _ = socat_process.communicate("show stat\n")
except:
socat_process.kill()
socat_process.wait()
raise
self.assertEqual(socat_process.poll(), 0)
# output is a csv
self.assertIn('family_default,FRONTEND,', output)
class TestTestRunnerEntryPoints(BalancerTestCase):
"""Check balancer has some entries for test runner.
"""
__partition_reference__ = 't'
@classmethod
def _getInstanceParameterDict(cls):
# type: () -> Dict
parameter_dict = super(
TestTestRunnerEntryPoints,
cls,
)._getInstanceParameterDict()
parameter_dict['dummy_http_server-test-runner-address-list'] = [
[
cls.getManagedResource("backend_0", EchoHTTPServer).hostname,
cls.getManagedResource("backend_0", EchoHTTPServer).port,
],
[
cls.getManagedResource("backend_1", EchoHTTPServer).hostname,
cls.getManagedResource("backend_1", EchoHTTPServer).port,
],
[
cls.getManagedResource("backend_2", EchoHTTPServer).hostname,
cls.getManagedResource("backend_2", EchoHTTPServer).port,
],
]
return parameter_dict
def test_use_proper_backend(self):
# requests are directed to proper backend based on URL path
test_runner_url_list = self.getRootPartitionConnectionParameterDict(
)['default-test-runner-url-list']
url_0, url_1, url_2 = test_runner_url_list
self.assertEqual(
urlparse.urlparse(url_0).netloc,
urlparse.urlparse(url_1).netloc)
self.assertEqual(
urlparse.urlparse(url_0).netloc,
urlparse.urlparse(url_2).netloc)
path_0 = '/VirtualHostBase/https/{netloc}/VirtualHostRoot/_vh_unit_test_0/something'.format(
netloc=urlparse.urlparse(url_0).netloc)
path_1 = '/VirtualHostBase/https/{netloc}/VirtualHostRoot/_vh_unit_test_1/something'.format(
netloc=urlparse.urlparse(url_0).netloc)
path_2 = '/VirtualHostBase/https/{netloc}/VirtualHostRoot/_vh_unit_test_2/something'.format(
netloc=urlparse.urlparse(url_0).netloc)
self.assertEqual(
{
requests.get(url_0 + 'something', verify=False).json()['Path']
for _ in range(10)
}, {path_0})
self.assertEqual(
{
requests.get(url_1 + 'something', verify=False).json()['Path']
for _ in range(10)
}, {path_1})
self.assertEqual(
{
requests.get(url_2 + 'something', verify=False).json()['Path']
for _ in range(10)
}, {path_2})
# If a test runner backend is down, others can be accessed.
self.getManagedResource("backend_0", EchoHTTPServer).close()
self.assertEqual(
{
requests.get(url_0 + 'something', verify=False).status_code
for _ in range(5)
}, {503})
self.assertEqual(
{
requests.get(url_1 + 'something', verify=False).json()['Path']
for _ in range(10)
}, {path_1})
class TestHTTP(BalancerTestCase): class TestHTTP(BalancerTestCase):
"""Check HTTP protocol """Check HTTP protocol with a HTTP/1.1 backend
""" """
@classmethod
def _getInstanceParameterDict(cls):
# type: () -> Dict
parameter_dict = super(TestHTTP, cls)._getInstanceParameterDict()
# use a HTTP/1.1 server instead
parameter_dict['dummy_http_server'] = [[cls.getManagedResource("HTTP/1.1 Server", EchoHTTP11Server).netloc, 1, False]]
return parameter_dict
__partition_reference__ = 'h' __partition_reference__ = 'h'
def test_http_version(self): def test_http_version(self):
# type: () -> None # type: () -> None
# https://stackoverflow.com/questions/37012486/python-3-x-how-to-get-http-version-using-requests-library/37012810
self.assertEqual( self.assertEqual(
requests.get(self.default_balancer_url, verify=False).raw.version, 11) subprocess.check_output([
'curl',
'--silent',
'--show-error',
'--output',
'/dev/null',
'--insecure',
'--write-out',
'%{http_version}',
self.default_balancer_url,
]),
'2',
)
def test_keep_alive(self): def test_keep_alive(self):
# type: () -> None # type: () -> None
...@@ -372,24 +513,27 @@ class TestHTTP(BalancerTestCase): ...@@ -372,24 +513,27 @@ class TestHTTP(BalancerTestCase):
class ContentTypeHTTPServer(ManagedHTTPServer): class ContentTypeHTTPServer(ManagedHTTPServer):
"""An HTTP Server which reply with content type from path. """An HTTP/1.1 Server which reply with content type from path.
For example when requested http://host/text/plain it will reply For example when requested http://host/text/plain it will reply
with Content-Type: text/plain header. with Content-Type: text/plain header.
The body is always "OK" The body is always "OK"
""" """
class RequestHandler(BaseHTTPRequestHandler): class RequestHandler(BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.1'
def do_GET(self): def do_GET(self):
# type: () -> None # type: () -> None
self.send_response(200) self.send_response(200)
if self.path == '/': if self.path == '/':
self.send_header("Content-Length", 0)
return self.end_headers() return self.end_headers()
content_type = self.path[1:] content_type = self.path[1:]
body = "OK"
self.send_header("Content-Type", content_type) self.send_header("Content-Type", content_type)
self.send_header("Content-Length", len(body))
self.end_headers() self.end_headers()
self.wfile.write("OK") self.wfile.write(body)
log_message = logging.getLogger(__name__ + '.ContentTypeHTTPServer').info log_message = logging.getLogger(__name__ + '.ContentTypeHTTPServer').info
...@@ -431,9 +575,9 @@ class TestContentEncoding(BalancerTestCase): ...@@ -431,9 +575,9 @@ class TestContentEncoding(BalancerTestCase):
resp = requests.get(urlparse.urljoin(self.default_balancer_url, content_type), verify=False) resp = requests.get(urlparse.urljoin(self.default_balancer_url, content_type), verify=False)
self.assertEqual(resp.headers['Content-Type'], content_type) self.assertEqual(resp.headers['Content-Type'], content_type)
self.assertEqual( self.assertEqual(
resp.headers['Content-Encoding'], resp.headers.get('Content-Encoding'),
'gzip', 'gzip',
'%s uses wrong encoding: %s' % (content_type, resp.headers['Content-Encoding'])) '%s uses wrong encoding: %s' % (content_type, resp.headers.get('Content-Encoding')))
self.assertEqual(resp.text, 'OK') self.assertEqual(resp.text, 'OK')
def test_no_gzip_encoding(self): def test_no_gzip_encoding(self):
...@@ -443,8 +587,8 @@ class TestContentEncoding(BalancerTestCase): ...@@ -443,8 +587,8 @@ class TestContentEncoding(BalancerTestCase):
self.assertEqual(resp.text, 'OK') self.assertEqual(resp.text, 'OK')
class CaucaseClientCertificate(ManagedResource): class CaucaseCertificate(ManagedResource):
"""A client certificate issued by a caucase services. """A certificate signed by a caucase service.
""" """
ca_crt_file = None # type: str ca_crt_file = None # type: str
...@@ -560,7 +704,7 @@ class TestFrontendXForwardedFor(BalancerTestCase): ...@@ -560,7 +704,7 @@ class TestFrontendXForwardedFor(BalancerTestCase):
def _getInstanceParameterDict(cls): def _getInstanceParameterDict(cls):
# type: () -> Dict # type: () -> Dict
frontend_caucase = cls.getManagedResource('frontend_caucase', CaucaseService) frontend_caucase = cls.getManagedResource('frontend_caucase', CaucaseService)
certificate = cls.getManagedResource('client_certificate', CaucaseClientCertificate) certificate = cls.getManagedResource('client_certificate', CaucaseCertificate)
certificate.request(u'shared frontend', frontend_caucase) certificate.request(u'shared frontend', frontend_caucase)
parameter_dict = super(TestFrontendXForwardedFor, cls)._getInstanceParameterDict() parameter_dict = super(TestFrontendXForwardedFor, cls)._getInstanceParameterDict()
...@@ -576,7 +720,7 @@ class TestFrontendXForwardedFor(BalancerTestCase): ...@@ -576,7 +720,7 @@ class TestFrontendXForwardedFor(BalancerTestCase):
def test_x_forwarded_for_added_when_verified_connection(self): def test_x_forwarded_for_added_when_verified_connection(self):
# type: () -> None # type: () -> None
client_certificate = self.getManagedResource('client_certificate', CaucaseClientCertificate) client_certificate = self.getManagedResource('client_certificate', CaucaseCertificate)
for backend in ('default', 'default-auth'): for backend in ('default', 'default-auth'):
balancer_url = json.loads(self.computer_partition.getConnectionParameterDict()['_'])[backend] balancer_url = json.loads(self.computer_partition.getConnectionParameterDict()['_'])[backend]
...@@ -586,7 +730,7 @@ class TestFrontendXForwardedFor(BalancerTestCase): ...@@ -586,7 +730,7 @@ class TestFrontendXForwardedFor(BalancerTestCase):
cert=(client_certificate.cert_file, client_certificate.key_file), cert=(client_certificate.cert_file, client_certificate.key_file),
verify=False, verify=False,
).json() ).json()
self.assertEqual(result['Incoming Headers'].get('x-forwarded-for').split(', ')[0], '1.2.3.4') self.assertEqual(result['Incoming Headers'].get('x-forwarded-for', '').split(', ')[0], '1.2.3.4')
def test_x_forwarded_for_stripped_when_not_verified_connection(self): def test_x_forwarded_for_stripped_when_not_verified_connection(self):
# type: () -> None # type: () -> None
...@@ -596,7 +740,7 @@ class TestFrontendXForwardedFor(BalancerTestCase): ...@@ -596,7 +740,7 @@ class TestFrontendXForwardedFor(BalancerTestCase):
headers={'X-Forwarded-For': '1.2.3.4'}, headers={'X-Forwarded-For': '1.2.3.4'},
verify=False, verify=False,
).json() ).json()
self.assertNotEqual(result['Incoming Headers'].get('x-forwarded-for').split(', ')[0], '1.2.3.4') self.assertNotEqual(result['Incoming Headers'].get('x-forwarded-for', '').split(', ')[0], '1.2.3.4')
balancer_url = json.loads(self.computer_partition.getConnectionParameterDict()['_'])['default-auth'] balancer_url = json.loads(self.computer_partition.getConnectionParameterDict()['_'])['default-auth']
with self.assertRaises(OpenSSL.SSL.Error): with self.assertRaises(OpenSSL.SSL.Error):
requests.get( requests.get(
...@@ -606,6 +750,30 @@ class TestFrontendXForwardedFor(BalancerTestCase): ...@@ -606,6 +750,30 @@ class TestFrontendXForwardedFor(BalancerTestCase):
) )
class TestServerTLSProvidedCertificate(BalancerTestCase):
"""Check that certificate and key can be provided as instance parameters.
"""
__partition_reference__ = 's'
@classmethod
def _getInstanceParameterDict(cls):
# type: () -> Dict
server_caucase = cls.getManagedResource('server_caucase', CaucaseService)
server_certificate = cls.getManagedResource('server_certificate', CaucaseCertificate)
server_certificate.request(cls._ipv4_address.decode(), server_caucase)
parameter_dict = super(TestServerTLSProvidedCertificate, cls)._getInstanceParameterDict()
with open(server_certificate.cert_file) as f:
parameter_dict['ssl']['cert'] = f.read()
with open(server_certificate.key_file) as f:
parameter_dict['ssl']['key'] = f.read()
return parameter_dict
def test_certificate_validates_with_provided_ca(self):
# type: () -> None
server_certificate = self.getManagedResource("server_certificate", CaucaseCertificate)
requests.get(self.default_balancer_url, verify=server_certificate.ca_crt_file)
class TestClientTLS(BalancerTestCase): class TestClientTLS(BalancerTestCase):
__partition_reference__ = 'c' __partition_reference__ = 'c'
...@@ -613,11 +781,11 @@ class TestClientTLS(BalancerTestCase): ...@@ -613,11 +781,11 @@ class TestClientTLS(BalancerTestCase):
def _getInstanceParameterDict(cls): def _getInstanceParameterDict(cls):
# type: () -> Dict # type: () -> Dict
frontend_caucase1 = cls.getManagedResource('frontend_caucase1', CaucaseService) frontend_caucase1 = cls.getManagedResource('frontend_caucase1', CaucaseService)
certificate1 = cls.getManagedResource('client_certificate1', CaucaseClientCertificate) certificate1 = cls.getManagedResource('client_certificate1', CaucaseCertificate)
certificate1.request(u'client_certificate1', frontend_caucase1) certificate1.request(u'client_certificate1', frontend_caucase1)
frontend_caucase2 = cls.getManagedResource('frontend_caucase2', CaucaseService) frontend_caucase2 = cls.getManagedResource('frontend_caucase2', CaucaseService)
certificate2 = cls.getManagedResource('client_certificate2', CaucaseClientCertificate) certificate2 = cls.getManagedResource('client_certificate2', CaucaseCertificate)
certificate2.request(u'client_certificate2', frontend_caucase2) certificate2.request(u'client_certificate2', frontend_caucase2)
parameter_dict = super(TestClientTLS, cls)._getInstanceParameterDict() parameter_dict = super(TestClientTLS, cls)._getInstanceParameterDict()
...@@ -646,7 +814,7 @@ class TestClientTLS(BalancerTestCase): ...@@ -646,7 +814,7 @@ class TestClientTLS(BalancerTestCase):
('client_certificate2', 'frontend_caucase2'), ('client_certificate2', 'frontend_caucase2'),
): ):
client_certificate = self.getManagedResource(client_certificate_name, client_certificate = self.getManagedResource(client_certificate_name,
CaucaseClientCertificate) CaucaseCertificate)
# when client certificate can be authenticated, backend receive the CN of # when client certificate can be authenticated, backend receive the CN of
# the client certificate in "remote-user" header # the client certificate in "remote-user" header
...@@ -692,10 +860,7 @@ class TestClientTLS(BalancerTestCase): ...@@ -692,10 +860,7 @@ class TestClientTLS(BalancerTestCase):
# simulate running updater service in the future, to confirm that it fetches # simulate running updater service in the future, to confirm that it fetches
# the new CRL and make sure balancer uses that new CRL. # the new CRL and make sure balancer uses that new CRL.
process = pexpect.spawnu( process = pexpect.spawnu("faketime +1day %s" % caucase_updater)
"faketime +1day %s" % caucase_updater,
env=dict(os.environ, PYTHONPATH=''),
)
process.logfile = DebugLogFile() process.logfile = DebugLogFile()
process.expect(u"Got new CRL.*Next wake-up at.*") process.expect(u"Got new CRL.*Next wake-up at.*")
......
...@@ -43,23 +43,44 @@ setUpModule # pyflakes ...@@ -43,23 +43,44 @@ setUpModule # pyflakes
class TestPublishedURLIsReachableMixin(object): class TestPublishedURLIsReachableMixin(object):
"""Mixin that checks that default page of ERP5 is reachable. """Mixin that checks that default page of ERP5 is reachable.
""" """
def _checkERP5IsReachable(self, url):
# What happens is that instanciation just create the services, but does not def _checkERP5IsReachable(self, base_url, site_id, verify):
# We access ERP5 trough a "virtual host", which should make
# ERP5 produce URLs using https://virtual-host-name:1234/virtual_host_root
# as base.
virtual_host_url = urlparse.urljoin(
base_url,
'/VirtualHostBase/https/virtual-host-name:1234/{}/VirtualHostRoot/_vh_virtual_host_root/'
.format(site_id))
# What happens is that instantiation just create the services, but does not
# wait for ERP5 to be initialized. When this test run ERP5 instance is # wait for ERP5 to be initialized. When this test run ERP5 instance is
# instanciated, but zope is still busy creating the site and haproxy replies # instantiated, but zope is still busy creating the site and haproxy replies
# with 503 Service Unavailable when zope is not started yet, with 404 when # with 503 Service Unavailable when zope is not started yet, with 404 when
# erp5 site is not created, with 500 when mysql is not yet reachable, so we # erp5 site is not created, with 500 when mysql is not yet reachable, so we
# retry in a loop until we get a succesful response. # configure this requests session to retry.
for i in range(1, 60): # XXX we should probably add a promise instead
r = requests.get(url, verify=False) # XXX can we get CA from caucase already ? session = requests.Session()
if r.status_code != requests.codes.ok: session.mount(
delay = i * 2 base_url,
self.logger.warn("ERP5 was not available, sleeping for %ds and retrying", delay) requests.adapters.HTTPAdapter(
time.sleep(delay) max_retries=requests.packages.urllib3.util.retry.Retry(
continue total=60,
r.raise_for_status() backoff_factor=.5,
break status_forcelist=(404, 500, 503))))
r = session.get(virtual_host_url, verify=verify, allow_redirects=False)
self.assertEqual(r.status_code, requests.codes.found)
# access on / are redirected to login form, with virtual host preserved
self.assertEqual(r.headers.get('location'), 'https://virtual-host-name:1234/virtual_host_root/login_form')
# login page can be rendered and contain the text "ERP5"
r = session.get(
urlparse.urljoin(base_url, '{}/login_form'.format(site_id)),
verify=verify,
allow_redirects=False,
)
self.assertEqual(r.status_code, requests.codes.ok)
self.assertIn("ERP5", r.text) self.assertIn("ERP5", r.text)
def test_published_family_default_v6_is_reachable(self): def test_published_family_default_v6_is_reachable(self):
...@@ -67,18 +88,24 @@ class TestPublishedURLIsReachableMixin(object): ...@@ -67,18 +88,24 @@ class TestPublishedURLIsReachableMixin(object):
""" """
param_dict = self.getRootPartitionConnectionParameterDict() param_dict = self.getRootPartitionConnectionParameterDict()
self._checkERP5IsReachable( self._checkERP5IsReachable(
urlparse.urljoin(param_dict['family-default-v6'], param_dict['site-id'])) param_dict['family-default-v6'],
param_dict['site-id'],
verify=False,
)
def test_published_family_default_v4_is_reachable(self): def test_published_family_default_v4_is_reachable(self):
"""Tests the IPv4 URL published by the root partition is reachable. """Tests the IPv4 URL published by the root partition is reachable.
""" """
param_dict = self.getRootPartitionConnectionParameterDict() param_dict = self.getRootPartitionConnectionParameterDict()
self._checkERP5IsReachable( self._checkERP5IsReachable(
urlparse.urljoin(param_dict['family-default'], param_dict['site-id'])) param_dict['family-default'],
param_dict['site-id'],
verify=False,
)
class TestDefaultParameters(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin): class TestDefaultParameters(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin):
"""Test ERP5 can be instanciated with no parameters """Test ERP5 can be instantiated with no parameters
""" """
__partition_reference__ = 'defp' __partition_reference__ = 'defp'
...@@ -92,9 +119,32 @@ class TestMedusa(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin): ...@@ -92,9 +119,32 @@ class TestMedusa(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin):
def getInstanceParameterDict(cls): def getInstanceParameterDict(cls):
return {'_': json.dumps({'wsgi': False})} return {'_': json.dumps({'wsgi': False})}
class TestJupyter(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin):
"""Test ERP5 Jupyter notebook
"""
__partition_reference__ = 'jupyter'
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'jupyter': {'enable': True}})}
class TestApacheBalancerPorts(ERP5InstanceTestCase): def test_jupyter_notebook_is_reachable(self):
"""Instanciate with two zope families, this should create for each family: param_dict = self.getRootPartitionConnectionParameterDict()
self.assertEqual(
'https://[%s]:8888/tree' % self._ipv6_address,
param_dict['jupyter-url']
)
result = requests.get(
param_dict['jupyter-url'], verify=False, allow_redirects=False)
self.assertEqual(
[requests.codes.found, True, '/login?next=%2Ftree'],
[result.status_code, result.is_redirect, result.headers['Location']]
)
class TestBalancerPorts(ERP5InstanceTestCase):
"""Instantiate with two zope families, this should create for each family:
- a balancer entry point with corresponding haproxy - a balancer entry point with corresponding haproxy
- a balancer entry point for test runner - a balancer entry point for test runner
""" """
...@@ -151,36 +201,25 @@ class TestApacheBalancerPorts(ERP5InstanceTestCase): ...@@ -151,36 +201,25 @@ class TestApacheBalancerPorts(ERP5InstanceTestCase):
3 + 5, 3 + 5,
len([p for p in all_process_info if p['name'].startswith('zope-')])) len([p for p in all_process_info if p['name'].startswith('zope-')]))
def test_apache_listen(self): def test_haproxy_listen(self):
# We have 2 families, apache should listen to a total of 3 ports per family # We have 2 families, haproxy should listen to a total of 3 ports per family
# normal access on ipv4 and ipv6 and test runner access on ipv4 only # normal access on ipv4 and ipv6 and test runner access on ipv4 only
with self.slap.instance_supervisor_rpc as supervisor: with self.slap.instance_supervisor_rpc as supervisor:
all_process_info = supervisor.getAllProcessInfo() all_process_info = supervisor.getAllProcessInfo()
process_info, = [p for p in all_process_info if p['name'] == 'apache'] process_info, = [p for p in all_process_info if p['name'].startswith('haproxy-')]
apache_process = psutil.Process(process_info['pid']) haproxy_master_process = psutil.Process(process_info['pid'])
haproxy_worker_process, = haproxy_master_process.children()
self.assertEqual( self.assertEqual(
sorted([socket.AF_INET] * 4 + [socket.AF_INET6] * 2), sorted([socket.AF_INET] * 4 + [socket.AF_INET6] * 2),
sorted([ sorted([
c.family c.family
for c in apache_process.connections() for c in haproxy_worker_process.connections()
if c.status == 'LISTEN' if c.status == 'LISTEN'
])) ]))
def test_haproxy_listen(self):
# There is one haproxy per family
with self.slap.instance_supervisor_rpc as supervisor:
all_process_info = supervisor.getAllProcessInfo()
process_info, = [
p for p in all_process_info if p['name'].startswith('haproxy-')
]
haproxy_process = psutil.Process(process_info['pid'])
self.assertEqual([socket.AF_INET, socket.AF_INET], [
c.family for c in haproxy_process.connections() if c.status == 'LISTEN'
])
class TestDisableTestRunner(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin): class TestDisableTestRunner(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin):
"""Test ERP5 can be instanciated without test runner. """Test ERP5 can be instantiated without test runner.
""" """
__partition_reference__ = 'distr' __partition_reference__ = 'distr'
@classmethod @classmethod
...@@ -199,20 +238,22 @@ class TestDisableTestRunner(ERP5InstanceTestCase, TestPublishedURLIsReachableMix ...@@ -199,20 +238,22 @@ class TestDisableTestRunner(ERP5InstanceTestCase, TestPublishedURLIsReachableMix
self.assertNotIn('runUnitTest', bin_programs) self.assertNotIn('runUnitTest', bin_programs)
self.assertNotIn('runTestSuite', bin_programs) self.assertNotIn('runTestSuite', bin_programs)
def test_no_apache_testrunner_port(self): def test_no_haproxy_testrunner_port(self):
# Apache only listen on two ports, there is no apache ports allocated for test runner # Haproxy only listen on two ports, there is no haproxy ports allocated for test runner
with self.slap.instance_supervisor_rpc as supervisor: with self.slap.instance_supervisor_rpc as supervisor:
all_process_info = supervisor.getAllProcessInfo() all_process_info = supervisor.getAllProcessInfo()
process_info, = [p for p in all_process_info if p['name'] == 'apache'] process_info, = [p for p in all_process_info if p['name'].startswith('haproxy')]
apache_process = psutil.Process(process_info['pid']) haproxy_master_process = psutil.Process(process_info['pid'])
haproxy_worker_process, = haproxy_master_process.children()
self.assertEqual( self.assertEqual(
sorted([socket.AF_INET, socket.AF_INET6]), sorted([socket.AF_INET, socket.AF_INET6]),
sorted( sorted(
c.family c.family
for c in apache_process.connections() for c in haproxy_worker_process.connections()
if c.status == 'LISTEN' if c.status == 'LISTEN'
)) ))
class TestZopeNodeParameterOverride(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin): class TestZopeNodeParameterOverride(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin):
"""Test override zope node parameters """Test override zope node parameters
""" """
......
Upgrade tests for ERP5 software release
##############################################################################
#
# Copyright (c) 2020 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from setuptools import setup, find_packages
version = '0.0.1.dev0'
name = 'slapos.test.upgrade_erp5'
with open("README.md") as f:
long_description = f.read()
setup(name=name,
version=version,
description="Upgrade test for SlapOS' ERP5 software release",
long_description=long_description,
long_description_content_type='text/markdown',
maintainer="Nexedi",
maintainer_email="info@nexedi.com",
url="https://lab.nexedi.com/nexedi/slapos",
packages=find_packages(),
install_requires=[
'slapos.core',
'supervisor',
'slapos.libnetworkcache',
'typing; python_version<"3"',
],
test_suite='test',
)
##############################################################################
#
# Copyright (c) 2020 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import glob
import json
import os
import tempfile
import time
import requests
import urlparse
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
from slapos.testing.testcase import installSoftwareUrlList
from slapos.testing.testcase import SlapOSNodeCommandError
from slapos.grid.utils import md5digest
old_software_release_url = 'https://lab.nexedi.com/nexedi/slapos/raw/1.0.167/software/erp5/software.cfg'
new_software_release_url = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software.cfg'))
_, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
old_software_release_url, software_id="upgrade_erp5")
def setUpModule():
installSoftwareUrlList(
SlapOSInstanceTestCase,
[old_software_release_url, new_software_release_url],
debug=SlapOSInstanceTestCase._debug,
)
class ERP5UpgradeTestCase(SlapOSInstanceTestCase):
# use short partition names for unix sockets
__partition_reference__ = 'u'
@classmethod
def setUpOldInstance(cls):
"""setUp hook executed while to old instance is running, before update
"""
pass
_current_software_url = old_software_release_url
@classmethod
def getSoftwareURL(cls):
return cls._current_software_url
@classmethod
def setUpClass(cls):
# request and instanciate with old software url
super(ERP5UpgradeTestCase, cls).setUpClass()
cls.setUpOldInstance()
# request instance on new software
cls._current_software_url = new_software_release_url
cls.logger.debug('requesting instance on new software')
cls.requestDefaultInstance()
# wait for slapos node instance
snapshot_name = "{}.{}.setUpClass new instance".format(
cls.__module__, cls.__name__)
try:
if cls._debug and cls.instance_max_retry:
try:
cls.slap.waitForInstance(max_retry=cls.instance_max_retry - 1)
except SlapOSNodeCommandError:
cls.slap.waitForInstance(debug=True)
else:
cls.slap.waitForInstance(max_retry=cls.instance_max_retry,
debug=cls._debug)
cls.logger.debug("instance on new software done")
except BaseException:
cls.logger.exception("Error during instance on new software")
cls._storeSystemSnapshot(snapshot_name)
cls._cleanup(snapshot_name)
cls.setUp = lambda self: self.fail('Setup Class failed.')
raise
else:
cls._storeSystemSnapshot(snapshot_name)
cls.computer_partition = cls.requestDefaultInstance()
class TestERP5Upgrade(ERP5UpgradeTestCase):
@classmethod
def setUpOldInstance(cls):
cls._default_instance_old_parameter_dict = json.loads(
cls.computer_partition.getConnectionParameterDict()['_'])
def test_published_url_is_same(self):
default_instance_new_parameter_dict = json.loads(
self.computer_partition.getConnectionParameterDict()['_'])
self.assertEqual(
default_instance_new_parameter_dict['family-default-v6'],
self._default_instance_old_parameter_dict['family-default-v6'],
)
def test_published_url_is_reachable(self):
default_instance_new_parameter_dict = json.loads(
self.computer_partition.getConnectionParameterDict()['_'])
# get certificate from caucase
with tempfile.NamedTemporaryFile(
prefix="ca.crt.pem",
mode="w",
delete=False,
) as ca_cert:
ca_cert.write(
requests.get(
urlparse.urljoin(
default_instance_new_parameter_dict['caucase-http-url'],
'/cas/crt/ca.crt.pem',
)).text)
ca_cert.flush()
# use a session to retry on failures, when ERP5 is not ready.
# (see also TestPublishedURLIsReachableMixin)
session = requests.Session()
session.mount(
default_instance_new_parameter_dict['family-default-v6'],
requests.adapters.HTTPAdapter(
max_retries=requests.packages.urllib3.util.retry.Retry(
total=60,
backoff_factor=.5,
status_forcelist=(404, 500, 503))))
session.get(
'{}/{}/login_form'.format(
default_instance_new_parameter_dict['family-default-v6'],
default_instance_new_parameter_dict['site-id'],
),
verify=False,
# TODO: we don't use caucase yet here.
# verify=ca_cert.name,
).raise_for_status()
def test_all_instances_use_new_software_release(self):
self.assertEqual(
{
os.path.basename(os.readlink(sr))
for sr in glob.glob(
os.path.join(
self.slap.instance_directory,
'*',
'software_release',
))
},
{md5digest(self.getSoftwareURL())},)
...@@ -42,7 +42,6 @@ output = ${buildout:directory}/template-default.cfg ...@@ -42,7 +42,6 @@ output = ${buildout:directory}/template-default.cfg
mode = 0644 mode = 0644
[versions] [versions]
slapos.recipe.template = 4.4
dnspython = 1.15.0 dnspython = 1.15.0
PyXML = 0.8.5 PyXML = 0.8.5
WebOb = 1.8.5 WebOb = 1.8.5
......
...@@ -13,6 +13,3 @@ url = ${:_profile_base_location_}/instance.cfg ...@@ -13,6 +13,3 @@ url = ${:_profile_base_location_}/instance.cfg
output = ${buildout:directory}/template.cfg output = ${buildout:directory}/template.cfg
md5sum = 9fccb9600a085691ab0f9a20cd615c01 md5sum = 9fccb9600a085691ab0f9a20cd615c01
mode = 0644 mode = 0644
[versions]
slapos.recipe.template = 4.4
...@@ -21,6 +21,3 @@ context = ...@@ -21,6 +21,3 @@ context =
gems += gems +=
fluent-plugin-wendelin==0.4 fluent-plugin-wendelin==0.4
fluent-plugin-bin fluent-plugin-bin
[versions]
slapos.recipe.template = 4.4
# THIS IS NOT A BUILDOUT FILE, despite purposedly using a compatible syntax.
# The only allowed lines here are (regexes):
# - "^#" comments, copied verbatim
# - "^[" section beginings, copied verbatim
# - lines containing an "=" sign which must fit in the following categorie.
# - "^\s*filename\s*=\s*path\s*$" where "path" is relative to this file
# Copied verbatim.
# - "^\s*hashtype\s*=.*" where "hashtype" is one of the values supported
# by the re-generation script.
# Re-generated.
# - other lines are copied verbatim
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# section inheritance (< = ...) are NOT supported (but you should really
# not need these here).
[instance-cfg]
filename = instance.cfg.in
md5sum = 270b39f448ec553fa9e203c5fbb49856
[buildout]
parts =
publish-connection-parameter
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[publish-connection-parameter]
recipe = slapos.cookbook:publish
url = https://[$${galene-wrapper:ip}]:$${galene-wrapper:port}
admin-user = $${admin-password:username}
admin-password = $${admin-password:passwd}
[slap-configuration]
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}
configuration.ice-servers.json = [{"urls":["stun:turn.api.nexedi.net:3478"]}]
[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
run = $${:var}/run
services = $${:etc}/service
data = $${:srv}/data
groups = $${:srv}/groups
recordings = $${:srv}/recordings
[galene-ssl]
recipe = plone.recipe.command
cert-file = $${directory:data}/cert.pem
key-file = $${directory:data}/key.pem
command = ${openssl:location}/bin/openssl req -newkey rsa:2048 -batch -new -x509 -days 3650 -nodes -keyout "$${:key-file}" -out "$${:cert-file}"
update-command =
stop-on-error = true
[admin-password]
recipe = slapos.cookbook:generate.password
storage-path = $${directory:data}/.passwd
username = admin
[ice-servers.json]
recipe = collective.recipe.template
input = inline:
$${slap-configuration:configuration.ice-servers.json}
output = $${directory:data}/ice-servers.json
[groups-json]
recipe = collective.recipe.template
input = inline:{
"public":true,
"op": [{"username":"$${admin-password:username}","password":"$${admin-password:passwd}"}],
"other": [],
"presenter": [{"username": "", "password": "nexedi"}],
"max-users":100
}
output = $${directory:groups}/public.json
[galene-wrapper]
recipe = slapos.cookbook:wrapper
port = 8443
ip = $${slap-configuration:ipv6-random}
command-line =
${galene:location}/bin/galene
-static ${galene-repository:location}/static
-recordings $${directory:recordings}
-groups $${directory:groups}
-data $${directory:data}
-http [$${:ip}]:$${:port}
wrapper-path = $${directory:services}/galene
depends =
$${ice-servers.json:recipe}
$${groups-json:recipe}
$${galene-ssl:recipe}
[buildout]
extends =
../../component/golang/buildout.cfg
../../component/openssl/buildout.cfg
../../stack/slapos.cfg
buildout.hash.cfg
parts =
slapos-cookbook
galene
eggs
instance-cfg
# eggs for instance.cfg
[eggs]
recipe = zc.recipe.egg
eggs =
plone.recipe.command
collective.recipe.template
[galene-repository]
<= git-repository
repository = https://lab.nexedi.com/nexedi/galene.git
revision = galene-0.2
location = ${buildout:parts-directory}/galene-repository
[galene]
recipe = slapos.recipe.cmmi
path = ${galene-repository:location}
location = @@LOCATION@@
golang = ${golang1.13:location}
configure-command = true
make-binary =
make-targets =
go install -ldflags='-s -w'
environment =
PATH=${:location}/bin:${:golang}/bin:${git:location}/bin:${pkgconfig:location}/bin:$PATH
GOPATH=${:location}
CGO_ENABLED=0
[instance-cfg]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/instance.cfg
...@@ -405,5 +405,4 @@ strip-top-level-dir = true ...@@ -405,5 +405,4 @@ strip-top-level-dir = true
cns.recipe.symlink = 0.2.3 cns.recipe.symlink = 0.2.3
docutils = 0.12 docutils = 0.12
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 4.3
z3c.recipe.scripts = 1.0.1 z3c.recipe.scripts = 1.0.1
...@@ -157,5 +157,4 @@ curl-bin = ${curl:location}/bin/curl ...@@ -157,5 +157,4 @@ curl-bin = ${curl:location}/bin/curl
dash-bin = ${dash:location}/bin/dash dash-bin = ${dash:location}/bin/dash
[versions] [versions]
slapos.recipe.template = 4.2
inotifyx = 0.2.2 inotifyx = 0.2.2
...@@ -40,6 +40,3 @@ recipe = slapos.recipe.build:download ...@@ -40,6 +40,3 @@ recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_buildout_section_name_} url = ${:_profile_base_location_}/${:_buildout_section_name_}
mode = 755 mode = 755
md5sum = 78b77a6bda9958f547f7d89b747731e3 md5sum = 78b77a6bda9958f547f7d89b747731e3
[versions]
slapos.recipe.template = 4.4
...@@ -53,7 +53,3 @@ context = ...@@ -53,7 +53,3 @@ context =
raw template_monitor ${monitor2-template:rendered} raw template_monitor ${monitor2-template:rendered}
# md5sum is fetched from buildout.hash.cfg and can be recalculated automatically by # md5sum is fetched from buildout.hash.cfg and can be recalculated automatically by
# calling update-hash # calling update-hash
# Pin versions of eggs used that are not already pinned by stack/slapos.cfg
[versions]
slapos.recipe.template = 4.4
[buildout]
parts =
switch-softwaretype
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[switch-softwaretype]
recipe = slapos.cookbook:softwaretype
default = ${instance_html5as:output}
[buildout]
parts =
switch-softwaretype
eggs-directory = {{ buildout['eggs-directory'] }}
develop-eggs-directory = {{ buildout['develop-eggs-directory'] }}
offline = true
[profile-common]
nginx_location = {{ nginx_location }}
dash_location = {{ dash_location }}
template_nginx_conf = {{ template_nginx_conf_target }}
template_mime_types = {{ template_mime_types_target }}
template_launcher = {{ template_launcher_target }}
[instance-html5as]
recipe = slapos.recipe.template:jinja2
template = {{ template_instance_html5as_target }}
rendered = ${buildout:directory}/${:filename}
filename = instance-html5as.cfg
context =
section buildout buildout
section parameter_list profile-common
[switch-softwaretype]
recipe = slapos.cookbook:softwaretype
default = ${instance-html5as:rendered}
#############################
#
# Deploy html5as instance
#
#############################
[buildout] [buildout]
parts = parts =
nginx_conf nginx_conf
downloader downloader
launcher
mime_types mime_types
launcher
publish-connection-information publish-connection-information
eggs-directory = ${buildout:eggs-directory} # Define egg directories to be the one from Software Release
develop-eggs-directory = ${buildout:develop-eggs-directory} # (/opt/slapgrid/...)
# Always the same.
eggs-directory = {{ buildout['eggs-directory'] }}
develop-eggs-directory = {{ buildout['develop-eggs-directory'] }}
offline = true offline = true
# partition tree # partition tree
...@@ -27,90 +35,97 @@ offline = true ...@@ -27,90 +35,97 @@ offline = true
# | | |- index.html # | | |- index.html
# | |- backup/ # | |- backup/
[rootdirectory] # Create all needed directories, depending on your needs
[directory]
recipe = slapos.cookbook:mkdirectory recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc home = ${buildout:directory}
var = $${buildout:directory}/var etc = ${:home}/etc
srv = $${buildout:directory}/srv var = ${:home}/var
tmp = $${buildout:directory}/tmp srv = ${:home}/srv
[basedirectory] [basedirectory]
recipe = slapos.cookbook:mkdirectory recipe = slapos.cookbook:mkdirectory
services = $${rootdirectory:etc}/run # Executables put here will be started but not monitored (for startup scripts)
log = $${rootdirectory:var}/log script = ${directory:etc}/run
run = $${rootdirectory:var}/run # Executables put here will be started and monitored (for daemons)
backup = $${rootdirectory:srv}/backup service = ${directory:etc}/service
data = $${rootdirectory:srv}/html5as log = ${directory:var}/log
run = ${directory:var}/run
backup = ${directory:srv}/backup
data = ${directory:srv}/html5as
[tempdirectory] [tempdirectory]
recipe = slapos.cookbook:mkdirectory recipe = slapos.cookbook:mkdirectory
client_body_temp_path = $${rootdirectory:tmp}/client_body_temp_path tmp = ${directory:home}/tmp
proxy_temp_path = $${rootdirectory:tmp}/proxy_temp_path client_body_temp_path = ${:tmp}/client_body_temp_path
fastcgi_temp_path = $${rootdirectory:tmp}/fastcgi_temp_path proxy_temp_path = ${:tmp}/proxy_temp_path
uwsgi_temp_path = $${rootdirectory:tmp}/uwsgi_temp_path fastcgi_temp_path = ${:tmp}/fastcgi_temp_path
scgi_temp_path = $${rootdirectory:tmp}/scgi_temp_path uwsgi_temp_path = ${:tmp}/uwsgi_temp_path
scgi_temp_path = ${:tmp}/scgi_temp_path
# List of options for html5as configuration
# It will run a simple nginx serving the content of srv/html5as
[html5as] [html5as]
# Options # Options
nb_workers = 2 nb_workers = 2
# Network # Network
ip = $${slap-network-information:global-ipv6} ip = ${slap-network-information:global-ipv6}
port = 8081 port = 8081
access_url = http://[${:ip}]:${:port}
# Paths # Paths
# Log # Log
path_pid = $${basedirectory:run}/nginx.pid path_pid = ${basedirectory:run}/nginx.pid
path_log = $${basedirectory:log}/nginx.log path_log = ${basedirectory:log}/nginx.log
path_access_log = $${basedirectory:log}/nginx.access.log path_access_log = ${basedirectory:log}/nginx.access.log
path_error_log = $${basedirectory:log}/nginx.error.log path_error_log = ${basedirectory:log}/nginx.error.log
path_tmp = $${buildout:directory}/tmp path_tmp = ${tempdirectory:tmp}
# Docroot # Docroot
docroot = $${basedirectory:data} docroot = ${basedirectory:data}
default_index = $${basedirectory:data}/index.html default_index = ${basedirectory:data}/index.html
# Config files # Config files
path_nginx_conf = $${rootdirectory:etc}/nginx.conf path_nginx_conf = ${directory:etc}/nginx.conf
path_mime_types = $${rootdirectory:etc}/mime_types path_mime_types = ${directory:etc}/mime_types
# Binaries
path_shell = {{ parameter_list['dash_location'] }}/bin/dash
# Executables # Executables
bin_nginx = ${nginx:location}/sbin/nginx bin_launcher = ${basedirectory:script}/launcher
bin_launcher = $${basedirectory:services}/launcher
bin_downloader = $${basedirectory:services}/downloader
# Utils # Utils
path_shell = ${dash:location}/bin/dash path_nginx = {{ parameter_list['nginx_location'] }}/sbin/nginx
path_curl = ${curl:location}/bin/curl
path_tar = ${tar:location}/bin/tar
# Render nginx conf
[nginx_conf] [nginx_conf]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
template = ${template_nginx_conf:location}/${template_nginx_conf:filename} template = {{ parameter_list['template_nginx_conf'] }}
rendered = $${html5as:path_nginx_conf} rendered = ${html5as:path_nginx_conf}
context = context =
section param_html5as html5as section param_html5as html5as
section param_tempdir tempdirectory section param_tempdir tempdirectory
# Render necessary mime types file for nginx
[mime_types] [mime_types]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
template = ${template_mime_types:location}/${template_mime_types:filename} template = {{ parameter_list['template_mime_types'] }}
rendered = $${html5as:path_mime_types} rendered = ${html5as:path_mime_types}
[downloader]
recipe = slapos.recipe.template:jinja2
template = ${template_downloader:location}/${template_downloader:filename}
rendered = $${html5as:bin_downloader}
mode = 700
context =
section param_html5as html5as
key download_url slap-parameter:download_url
# Render the script launching nginx
[launcher] [launcher]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
template = ${template_launcher:location}/${template_launcher:filename} template = {{ parameter_list['template_launcher'] }}
rendered = $${html5as:bin_launcher} rendered = ${html5as:bin_launcher}
mode = 700 mode = 700
context = context =
section param_html5as html5as section param_html5as html5as
# Simple command to put content in the docroot
[downloader]
recipe = plone.recipe.command
command = rm -r ${html5as:docroot}/*; echo "Hello World!" > ${html5as:docroot}/index.html
# Publish nginx address
[publish-connection-information] [publish-connection-information]
recipe = slapos.cookbook:publish recipe = slapos.cookbook:publish
server_url = http://[$${html5as:ip}]:$${html5as:port} server_url = ${html5as:access_url}
[buildout] [buildout]
extends = extends =
# "slapos" stack describes basic things needed for 99.9% of SlapOS Software
# Releases
../../stack/slapos.cfg ../../stack/slapos.cfg
# Extend here component profiles, like openssl, apache, mariadb, curl...
# Or/and extend a stack (lamp, tomcat) that does most of the work for you
# In this example we extend needed components for html5as.
../../component/nginx/buildout.cfg ../../component/nginx/buildout.cfg
../../component/curl/buildout.cfg
../../component/dash/buildout.cfg ../../component/dash/buildout.cfg
../../component/tar/buildout.cfg
parts = parts =
dash # Call installation of slapos.cookbook egg defined in stack/slapos.cfg (needed
tar # in 99,9% of Slapos Software Releases)
curl
nginx
slapos-cookbook slapos-cookbook
template # Call creation of instance.cfg file that will be called for deployment of
template_nginx_conf # instance
template_downloader template-cfg
template_launcher
template_mime_types
instance_html5as
# Download instance.cfg.in (buildout profile used to deployment of instance),
[template] # replace all {{ foo_bar }} parameters by real values
recipe = slapos.recipe.template # The recipe, template and mode are fetched from jijna-template
url = ${:_profile_base_location_}/instance.cfg [template-cfg]
output = ${buildout:directory}/template.cfg recipe = slapos.recipe.template:jinja2
md5sum = 918e0d6513e4d1c92051431d83261dab rendered = ${buildout:directory}/template.cfg
template = ${:_profile_base_location_}/${:filename}
filename = instance.cfg.in
md5sum = 5a6ebc126bcad3cdff1b51fb51f82a35
mode = 0644 mode = 0644
context =
section buildout buildout
key nginx_location nginx:location
key dash_location dash:location
key template_nginx_conf_target template_nginx_conf:target
key template_mime_types_target template_mime_types:target
key template_launcher_target template_launcher:target
key template_instance_html5as_target instance_html5as:target
# Download instance_html5as.cfg.in
[instance_html5as] [instance_html5as]
recipe = slapos.recipe.template recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/instance_html5as.cfg url = ${:_profile_base_location_}/${:_update_hash_filename_}
output = ${buildout:directory}/template_html5as.cfg _update_hash_filename_ = instance_html5as.cfg.in
md5sum = 41cb6178f760238ca276854873ef9364 md5sum = 4a8c98cc5ca141f78f14fb9cec203cb8
mode = 0644 mode = 0644
[template_nginx_conf] [template_nginx_conf]
recipe = slapos.recipe.build:download recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/nginx_conf.in url = ${:_profile_base_location_}/${:_update_hash_filename_}
_update_hash_filename_ = templates/nginx_conf.in
md5sum = 61dc4c82bf48563228ce4dea6c5c6319 md5sum = 61dc4c82bf48563228ce4dea6c5c6319
filename = nginx_conf.in
mode = 0644 mode = 0644
location = ${buildout:parts-directory}/${:_buildout_section_name_}
[template_launcher] [template_launcher]
recipe = slapos.recipe.build:download recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/launcher.in url = ${:_profile_base_location_}/${:_update_hash_filename_}
md5sum = acf5bb55ceac2e826259d28ed5c1de3a _update_hash_filename_ = templates/launcher.in
filename = launcher.in md5sum = 8d4d3152f5125f73d0c3f3ea1c3699dd
mode = 0644
location = ${buildout:parts-directory}/${:_buildout_section_name_}
[template_downloader]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/downloader.in
md5sum = 9779e2db6c73d282f802b3407b390ede
filename = downloader.in
mode = 0644 mode = 0644
location = ${buildout:parts-directory}/${:_buildout_section_name_}
[template_mime_types] [template_mime_types]
recipe = slapos.recipe.build:download recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/mime_types.in url = ${:_profile_base_location_}/${:_update_hash_filename_}
_update_hash_filename_ = templates/mime_types.in
md5sum = 4ef94a7b458d885cd79ba0b930a5727e md5sum = 4ef94a7b458d885cd79ba0b930a5727e
filename = mime_types.in
mode = 0644 mode = 0644
location = ${buildout:parts-directory}/${:_buildout_section_name_}
# Pin versions of eggs used that are not already pinned by stack/slapos.cfg
[versions] [versions]
async = 0.6.1
gitdb = 0.5.4
pycrypto = 2.6
rdiff-backup = 1.0.5+SlapOSPatched001
slapos.recipe.template = 4.4 slapos.recipe.template = 4.4
smmap = 0.8.2
plone.recipe.command = 1.1
#! {{ param_html5as['path_shell'] }}
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
# Remove exsistant website
rm -r {{ param_html5as['docroot'] }}/*
# Download and extract website tarball into docroot directory
exec {{ param_html5as['path_curl'] }} -ks {{ download_url }} | {{ param_html5as['path_tar'] }} -z -x -C {{ param_html5as['docroot'] }}
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
# BEWARE: It will be overwritten automatically # BEWARE: It will be overwritten automatically
# Run nginx # Run nginx
exec {{ param_html5as['bin_nginx'] }} -c {{ param_html5as['path_nginx_conf'] }} exec {{ param_html5as['path_nginx'] }} -c {{ param_html5as['path_nginx_conf'] }}
...@@ -47,4 +47,3 @@ md5sum = 8cde04bfd0c0e9bd56744b988275cfd8 ...@@ -47,4 +47,3 @@ md5sum = 8cde04bfd0c0e9bd56744b988275cfd8
PyRSS2Gen = 1.1 PyRSS2Gen = 1.1
cns.recipe.symlink = 0.2.3 cns.recipe.symlink = 0.2.3
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 4.4
...@@ -50,5 +50,4 @@ mode = 0644 ...@@ -50,5 +50,4 @@ mode = 0644
# but '1.3.4nxd2-SlapOSPatched001'. # but '1.3.4nxd2-SlapOSPatched001'.
gunicorn = 19.1.1 gunicorn = 19.1.1
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 2.4.3
inotifyx = 0.2.2 inotifyx = 0.2.2
...@@ -118,7 +118,6 @@ output = ${buildout:directory}/runTestSuite.in ...@@ -118,7 +118,6 @@ output = ${buildout:directory}/runTestSuite.in
[versions] [versions]
slapos.recipe.template = 4.4
selenium = 3.14.1 selenium = 3.14.1
urllib3 = 1.24 urllib3 = 1.24
certifi = 2018.10.15 certifi = 2018.10.15
...@@ -75,7 +75,7 @@ class ERP5Kernel(Kernel): ...@@ -75,7 +75,7 @@ class ERP5Kernel(Kernel):
self.title = None self.title = None
# Allowed HTTP request code list for making request to erp5 from Kernel # Allowed HTTP request code list for making request to erp5 from Kernel
# This list should be to used check status_code before making requests to erp5 # This list should be to used check status_code before making requests to erp5
self.allowed_HTTP_request_code_list = range(500, 511) self.allowed_HTTP_request_code_list = list(range(500, 511))
# Append request code 200 in the allowed HTTP status code list # Append request code 200 in the allowed HTTP status code list
self.allowed_HTTP_request_code_list.append(200) self.allowed_HTTP_request_code_list.append(200)
......
...@@ -13,21 +13,21 @@ ...@@ -13,21 +13,21 @@
# section inheritance (< = ...) are NOT supported (but you should really # section inheritance (< = ...) are NOT supported (but you should really
# not need these here). # not need these here).
[instance-jupyter-notebook] [instance]
filename = instance.cfg.in filename = instance.cfg.in
md5sum = 1d5fe6cc4e48672ae7be1c223794a932 md5sum = f33fc954eba47b5ddbebc72c453304e3
[instance-jupyter]
filename = instance-jupyter.cfg.in
md5sum = 9340498841caa5771f40f8c9e561eacd
[jupyter-notebook-config] [jupyter-notebook-config]
filename = jupyter_notebook_config.py.jinja filename = jupyter_notebook_config.py.jinja
md5sum = 720e90a829c63371696bc3009917a743 md5sum = 6e01da7d35c1d65d4a450b0f011b296d
[jupyter-set-password]
filename = jupyter_set_password.cgi.jinja
md5sum = b8d31441780b524a7e52d1710dd78385
[erp5-kernel] [erp5-kernel]
filename = ERP5kernel.py filename = ERP5kernel.py
md5sum = 7d5309fe79afbcb455c0d8181b42e56c md5sum = da04b99b70b2e327c9e9b4cdd056098e
[kernel-json] [kernel-json]
filename = kernel.json.jinja filename = kernel.json.jinja
...@@ -35,4 +35,4 @@ md5sum = 33547be93a67530165e079dc3ecfdac3 ...@@ -35,4 +35,4 @@ md5sum = 33547be93a67530165e079dc3ecfdac3
[custom-js] [custom-js]
filename = custom.js filename = custom.js
md5sum = 40d938bb09261c65421a7725b40f87dc md5sum = 295aeee765bc4d09bf0686021f32f72c
...@@ -81,41 +81,51 @@ ...@@ -81,41 +81,51 @@
* @static * @static
*/ */
$([Jupyter.events]).on('notebook_loaded.Notebook', function(){ function prependERP5Help() {
var kernelname = Jupyter.notebook.kernel_selector.current_selection; var kernelname = Jupyter.notebook.kernel_selector.current_selection;
var display_text="<div class='output_subarea output_text output_result'>\ var display_text = "<div class='output_subarea output_text output_result'>\
<pre>Follow these steps to customize your notebook with ERP5 kernel :-</br>\ <pre>Follow these steps to customize your notebook with ERP5 kernel :-</br>\
1. Make sure you have 'erp5_data_notebook' business template installed in your ERP5</br>\ 1. Make sure you have 'erp5_data_notebook' business template installed in your ERP5</br>\
2. <b>%erp5_user &lt;your_erp5_username&gt;</b></br>\ 2. <b>%erp5_url &lt;your_erp5_url&gt;/Base_executeJupyter</b></br>\
3. <b>%erp5_password &lt;your_erp5_password&gt;</b></br>\ 3. <b>%erp5_user &lt;your_erp5_username&gt;</b></br>\
4. <b>%notebook_set_reference &lt;your_notebook_reference&gt;</b></br>\ 4. <b>%erp5_password &lt;your_erp5_password&gt;</b></br>\
It would be better to set the reference to match with erp5 reference pattern.</br>\ 5. <b>%notebook_set_reference &lt;your_notebook_reference&gt;</b></br>\
5. As soon as you see 'Please Proceed' message you can now access your erp5 using notebook.</br>\ It would be better to set the reference to match with erp5 reference pattern.</br>\
<p><u>OTHER USEFUL MAGICS</u> -</br>\ 6. As soon as you see 'Please Proceed' message you can now access your erp5 using notebook.</br>\
<b>%my_notebooks</b> -This is used to display all the notebooks created by the specific user.</br>\ <p><u>OTHER USEFUL MAGICS</u> -</br>\
<b>%notebook_set_title</b> -This sets the title of the current notebook.</br>\ <b>%my_notebooks</b> -This is used to display all the notebooks created by the specific user.</br>\
NOTE: Do not dynamically alter imported module objects as they are not being saved in DB, </br>\ <b>%notebook_set_title</b> -This sets the title of the current notebook.</br>\
so changes to them would be disregarded and would throw an error.</br>\ NOTE: Do not dynamically alter imported module objects as they are not being saved in DB, </br>\
<p><u>About classes, functions and global state on modules:</u></p>\ so changes to them would be disregarded and would throw an error.</br>\
Your code is going to be executed by ERP5, which can have many nodes </br>\ <p><u>About classes, functions and global state on modules:</u></p>\
and there is no guarantee that your code is always going to be executed by the same server.</br>\ Your code is going to be executed by ERP5, which can have many nodes </br>\
This means that objects which cannot be stored in the ZODB, like functions, classes and modules </br>\ and there is no guarantee that your code is always going to be executed by the same server.</br>\
won't be available across nodes. To solve this issue, you need to use a special object </br>\ This means that objects which cannot be stored in the ZODB, like functions, classes and modules </br>\
called 'environment' to store your global setup. This object was designed to hold global </br>\ won't be available across nodes. To solve this issue, you need to use a special object </br>\
state and restore it for each code cell. Example:</br></br>\ called 'environment' to store your global setup. This object was designed to hold global </br>\
<b>def my_setup():</br>\ state and restore it for each code cell. Example:</br></br>\
# import modules, define functions and classes</br>\ <b>def my_setup():</br>\
# and set global state on modules</br>\ # import modules, define functions and classes</br>\
# return dict of variables to be available in code cells</br>\ # and set global state on modules</br>\
{'my_var': 1}</br>\ # return dict of variables to be available in code cells</br>\
environment.define(my_setup, 'my custom setup')</b></br></br>\ {'my_var': 1}</br>\
After you execute this cell, the <b>my_setup</b> function will run before each of the</br>\ environment.define(my_setup, 'my custom setup')</b></br></br>\
following cells and the <b>my_var</b> variable will be created and set to 1.</br></br>\ After you execute this cell, the <b>my_setup</b> function will run before each of the</br>\
<b>WARNING:</b> it is not recommended to have too many setup functions in the environment, </br>\ following cells and the <b>my_var</b> variable will be created and set to 1.</br></br>\
because they will be executed in every code cell and can cause a substantial slow down.\ <b>WARNING:</b> it is not recommended to have too many setup functions in the environment, </br>\
</pre></div>"; because they will be executed in every code cell and can cause a substantial slow down.\
if (kernelname=="erp5"){ </pre></div>";
$('div#notebook-container').prepend(display_text);
} if (kernelname=="erp5"){
$('div#notebook-container').prepend(display_text);
}
}
define([
'base/js/namespace',
'base/js/promises'
], function(Jupyter, promises) {
promises.notebook_loaded.then(function() {
prependERP5Help();
}); });
});
\ No newline at end of file
{% set additional_frontend = slapparameter_dict.get('frontend-additional-instance-guid') %}
[buildout]
parts =
instance
publish-connection-parameter
jupyter-notebook-config
erp5-kernel
kernel-json
custom-js
frontend-promise
{% if additional_frontend %}
frontend-additional-promise
{% endif %}
monitor-base
extends =
{{ monitor_template_rendered }}/template-monitor.cfg
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[slapconfiguration]
recipe = slapos.cookbook:slapconfiguration.serialised
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}
# ERP5 URL to use in Jupyter by default
# default value is empty - which means no default ERP5 URL
configuration.erp5-url =
[instance-parameter]
port = 8888
host = ${slapconfiguration:ipv6-random}
cert_file = ${generate-certificate:cert_file}
key_file = ${generate-certificate:key_file}
logfile = ${directory:log}/jupyter_notebook.log
notebook_dir = ${directory:notebook_dir}
[slap-parameter]
frontend-software-type = RootSoftwareInstance
frontend-software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
frontend-instance-guid =
frontend-instance-name = Jupyter Frontend
frontend-additional-software-type = RootSoftwareInstance
frontend-additional-software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
frontend-additional-instance-guid =
frontend-additional-instance-name = Jupyter Frontend Additional
[dynamic-jinja2-template-base]
recipe = slapos.recipe.template:jinja2
mode = 0644
[generate-certificate]
; TODO: there is a slapos recipe to generate certificates. Use it instead
recipe = plone.recipe.command
command =
if [ ! -e ${instance-parameter:key_file} ]
then
{{ openssl_output }} req -x509 -nodes -days 3650 \
-subj "/C=AA/ST=X/L=X/O=Dis/CN=${instance-parameter:host}" \
-newkey rsa:1024 -keyout ${instance-parameter:key_file} \
-out ${instance-parameter:cert_file}
fi
update-command = ${:command}
cert_file = ${directory:etc}/jupyter_cert.crt
key_file = ${directory:etc}/jupyter_cert.key
[instance]
recipe = slapos.cookbook:wrapper
command-line =
{{ bin_directory }}/jupyter-lab
--no-browser
--ip=${instance-parameter:host}
--port=${instance-parameter:port}
--port-retries=0
--certfile=${instance-parameter:cert_file}
--keyfile=${instance-parameter:key_file}
--notebook-dir=${instance-parameter:notebook_dir}
--log-level="DEBUG"
wrapper-path = ${directory:service}/jupyter-lab
environment =
JUPYTER_PATH=${directory:jupyter_dir}
JUPYTER_CONFIG_DIR=${directory:jupyter_config_dir}
JUPYTER_RUNTIME_DIR=${directory:jupyter_runtime_dir}
LANG=C.UTF-8
[jupyter-password]
recipe = slapos.cookbook:generate.password
bytes = 10
[jupyter-notebook-config]
<= dynamic-jinja2-template-base
template = {{ jupyter_config_location }}/{{ jupyter_config_filename }}
rendered = ${directory:jupyter_config_dir}/jupyter_notebook_config.py
mode = 0744
context =
key password jupyter-password:passwd
raw gcc_location {{ gcc_location }}
raw cythonplus_repository {{ cythonplus_repository }}
[directory]
recipe = slapos.cookbook:mkdirectory
home = ${buildout:directory}
etc = ${:home}/etc
var = ${:home}/var
script = ${:etc}/run/
service = ${:etc}/service
log = ${:var}/log
notebook_dir = ${:var}/notebooks
# Add folders to explicitly define jupyter directory
jupyter_dir = ${:home}/jupyter
jupyter_config_dir = ${:jupyter_dir}/etc
jupyter_kernel_dir = ${:jupyter_dir}/kernels
jupyter_runtime_dir = ${:jupyter_dir}/runtime
jupyter_custom_dir = ${:jupyter_config_dir}/custom
jupyter_nbextensions_dir = ${:jupyter_dir}/nbextensions
erp5_kernel_dir = ${:jupyter_kernel_dir}/ERP5
[request-slave-frontend-base]
recipe = slapos.cookbook:requestoptional
server-url = ${slap-connection:server-url}
key-file = ${slap-connection:key-file}
cert-file = ${slap-connection:cert-file}
computer-id = ${slap-connection:computer-id}
partition-id = ${slap-connection:partition-id}
slave = true
config-type = notebook
config-url = https://[${instance-parameter:host}]:${instance-parameter:port}
return = secure_access
[request-slave-frontend]
<= request-slave-frontend-base
software-url = ${slap-parameter:frontend-software-url}
software-type = ${slap-parameter:frontend-software-type}
name = ${slap-parameter:frontend-instance-name}
sla-instance_guid = ${slap-parameter:frontend-instance-guid}
[frontend-promise]
<= monitor-promise-base
module = check_url_available
name = frontend_promise.py
config-url = ${publish-connection-parameter:url}
{% if additional_frontend %}
[request-slave-frontend-additional]
<= request-slave-frontend-base
software-url = ${slap-parameter:frontend-additional-software-url}
software-type = ${slap-parameter:frontend-additional-software-type}
name = ${slap-parameter:frontend-additional-instance-name}
sla-instance_guid = ${slap-parameter:frontend-additional-instance-guid}
[frontend-additional-promise]
<= monitor-promise-base
module = check_url_available
name = frontend_additional_promise.py
config-url = ${publish-connection-parameter:url-additional}
{% endif %}
[monitor-instance-parameter]
monitor-base-url = ${monitor-frontend-promise:url}
# In case you're using a developer instance you should edit these in:
# monitor-base-url = ${monitor-httpd-conf-parameter:url}
# cors-domains = softinstXXXXX.host.vifib.net (or equivalent)
# interface-url = https://softinstXXXXX.host.vifib.net/erp5/web_site_module/monitoring_rjs_unsafe
instance-configuration =
raw jupyter-password ${jupyter-password:passwd}
[publish-connection-parameter]
recipe = slapos.cookbook:publish.serialised
jupyter-classic-url = ${request-slave-frontend:connection-secure_access}/tree
url = ${:jupyter-classic-url}
jupyterlab-url = ${request-slave-frontend:connection-secure_access}/lab
{% if additional_frontend %}
jupyter-classic-url-additional = ${request-slave-frontend-additional:connection-secure_access}/tree
url-additional = ${:jupyter-classic-url-additional}
jupyterlab-url-additional = ${request-slave-frontend-additional:connection-secure_access}/lab
{% endif %}
password = ${jupyter-password:passwd}
[erp5-kernel]
recipe = slapos.cookbook:symbolic.link
link-binary = {{ erp5_kernel_location }}/{{ erp5_kernel_filename }}
target-directory = ${directory:erp5_kernel_dir}
[kernel-json]
<= dynamic-jinja2-template-base
template = {{ kernel_json_location }}/{{ kernel_json_filename }}
rendered = ${directory:erp5_kernel_dir}/kernel.json
# Use python2.7 executable bin file for kernel config
context =
raw python_executable {{ python_executable }}
raw kernel_dir ${erp5-kernel:target-directory}/{{ erp5_kernel_filename }}
key erp5_url slapconfiguration:configuration.erp5-url
raw display_name ERP5
raw language_name python
[custom-js]
recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:jupyter_custom_dir}
link-binary = {{ custom_js_location }}/custom.js
[buildout] [buildout]
parts = parts =
instance switch_softwaretype
jupyter_notebook
read-knowledge0
publish-connection-parameter
jupyter-notebook-config
erp5-kernel
kernel-json
custom-js
monitor-base
extends =
{{ monitor_template_rendered }}/template-monitor.cfg
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
eggs-directory = {{ eggs_directory }} [switch_softwaretype]
develop-eggs-directory = {{ develop_eggs_directory }} recipe = slapos.cookbook:switch-softwaretype
offline = true default = $${:jupyter}
jupyter = instance-jupyter:rendered
RootSoftwareInstance = $${:default}
[slapconfiguration] [slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised recipe = slapos.cookbook:slapconfiguration.serialised
computer = ${slap-connection:computer-id} computer = $${slap-connection:computer-id}
partition = ${slap-connection:partition-id} partition = $${slap-connection:partition-id}
url = ${slap-connection:server-url} url = $${slap-connection:server-url}
key = ${slap-connection:key-file} key = $${slap-connection:key-file}
cert = ${slap-connection:cert-file} cert = $${slap-connection:cert-file}
# ERP5 URL to use in Jupyter by default [instance-jupyter]
# default value is empty - which means no default ERP5 URL
configuration.erp5-url =
[instance-parameter]
port = 8888
host = ${slapconfiguration:ipv6-random}
cert_file = ${generate-certificate:cert_file}
key_file = ${generate-certificate:key_file}
logfile = ${directory:log}/jupyter_notebook.log
notebook_dir = ${directory:notebook_dir}
[dynamic-jinja2-template-base]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
filename = instance-jupyter.cfg.in
template = ${instance:_profile_base_location_}/$${:filename}
rendered = $${buildout:directory}/template.cfg
mode = 0644 mode = 0644
[generate-certificate]
; TODO: there is a slapos recipe to generate certificates. Use it instead
recipe = plone.recipe.command
command =
if [ ! -e ${instance-parameter:key_file} ]
then
{{ openssl_output }} req -x509 -nodes -days 3650 \
-subj "/C=AA/ST=X/L=X/O=Dis/CN=${instance-parameter:host}" \
-newkey rsa:1024 -keyout ${instance-parameter:key_file} \
-out ${instance-parameter:cert_file}
fi
update-command = ${:command}
cert_file = ${directory:etc}/jupyter_cert.crt
key_file = ${directory:etc}/jupyter_cert.key
[instance]
recipe = slapos.cookbook:wrapper
command-line =
{{ bin_directory }}/jupyter-lab
--no-browser
--ip=${instance-parameter:host}
--port=${instance-parameter:port}
--port-retries=0
--certfile=${instance-parameter:cert_file}
--keyfile=${instance-parameter:key_file}
--notebook-dir=${instance-parameter:notebook_dir}
--log-level="DEBUG"
wrapper-path = ${directory:service}/jupyter-lab
environment =
JUPYTER_PATH=${directory:jupyter_dir}
JUPYTER_CONFIG_DIR=${directory:jupyter_config_dir}
JUPYTER_RUNTIME_DIR=${directory:jupyter_runtime_dir}
LANG=C.UTF-8
[jupyter-notebook-config]
<= dynamic-jinja2-template-base
template = {{ jupyter_config_location }}/{{ jupyter_config_filename }}
rendered = ${directory:jupyter_config_dir}/jupyter_notebook_config.py
mode = 0744
context =
raw config_cfg ${buildout:directory}/knowledge0.cfg
[directory]
recipe = slapos.cookbook:mkdirectory
home = ${buildout:directory}
etc = ${:home}/etc
var = ${:home}/var
script = ${:etc}/run/
service = ${:etc}/service
log = ${:var}/log
notebook_dir = ${:var}/notebooks
# Add folders to explicitly define jupyter directory
jupyter_dir = ${:home}/jupyter
jupyter_config_dir = ${:jupyter_dir}/etc
jupyter_kernel_dir = ${:jupyter_dir}/kernels
jupyter_runtime_dir = ${:jupyter_dir}/runtime
jupyter_custom_dir = ${:jupyter_config_dir}/custom
jupyter_nbextensions_dir = ${:jupyter_dir}/nbextensions
erp5_kernel_dir = ${:jupyter_kernel_dir}/ERP5
[jupyter_notebook]
# This part is called like this because knowledge0.write uses the part name for
# the section name in the config file.
recipe = slapos.cookbook:zero-knowledge.write
password =
filename = knowledge0.cfg
[read-knowledge0]
recipe = slapos.cookbook:zero-knowledge.read
filename = knowledge0.cfg
password =
[monitor-instance-parameter]
monitor-base-url = ${monitor-frontend-promise:url}
# In case you're using a developer instance you should edit these in:
# monitor-base-url = ${monitor-httpd-conf-parameter:url}
# cors-domains = softinstXXXXX.host.vifib.net (or equivalent)
# interface-url = https://softinstXXXXX.host.vifib.net/erp5/web_site_module/monitoring_rjs_unsafe
instance-configuration =
raw jupyter-password ${read-knowledge0:password}
[publish-connection-parameter]
recipe = slapos.cookbook:publish.serialised
jupyter-classic-url = https://[${instance-parameter:host}]:${instance-parameter:port}/tree
url = ${:jupyter-classic-url}
jupyterlab-url = https://[${instance-parameter:host}]:${instance-parameter:port}/lab
[erp5-kernel]
recipe = slapos.cookbook:symbolic.link
link-binary = {{ erp5_kernel_location }}/{{ erp5_kernel_filename }}
target-directory = ${directory:erp5_kernel_dir}
[kernel-json]
<= dynamic-jinja2-template-base
template = {{ kernel_json_location }}/{{ kernel_json_filename }}
rendered = ${directory:erp5_kernel_dir}/kernel.json
# Use python2.7 executable bin file for kernel config
context = context =
raw python_executable {{ python_executable }} key slapparameter_dict slap-configuration:configuration
raw kernel_dir ${erp5-kernel:target-directory}/{{ erp5_kernel_filename }} raw bin_directory ${buildout:bin-directory}
key erp5_url slapconfiguration:configuration.erp5-url raw develop_eggs_directory ${buildout:develop-eggs-directory}
raw display_name ERP5 raw eggs_directory ${buildout:eggs-directory}
raw language_name python raw openssl_output ${openssl-output:openssl}
raw python_executable ${jupyter:python_executable}
[custom-js] raw jupyter_config_location ${jupyter-notebook-config:location}
recipe = slapos.cookbook:symbolic.link raw jupyter_config_filename ${jupyter-notebook-config:filename}
target-directory = ${directory:jupyter_custom_dir} raw erp5_kernel_location ${erp5-kernel:location}
link-binary = {{ custom_js_location }}/custom.js raw erp5_kernel_filename ${erp5-kernel:filename}
raw kernel_json_location ${kernel-json:location}
raw kernel_json_filename ${kernel-json:filename}
raw custom_js_location ${custom-js:location}
raw custom_js_filename ${custom-js:filename}
raw monitor_template_rendered ${buildout:directory}
raw cythonplus_repository ${cythonplus-repository:location}
raw gcc_location ${gcc:prefix}
...@@ -2,37 +2,13 @@ ...@@ -2,37 +2,13 @@
This script initializes Jupyter's configuration such as passwords and other This script initializes Jupyter's configuration such as passwords and other
things. It is run by IPython hence why it can use functions like get_config(). things. It is run by IPython hence why it can use functions like get_config().
''' '''
import ConfigParser import configparser
import random
from notebook.auth import passwd from notebook.auth import passwd
import os import os
def random_password(length = 10):
result = ""
for i in range(0, length):
result = result + chr(random.randint(0, 25) + ord('a'))
return result
knowledge_0 = '{{ config_cfg }}'
if not os.path.exists(knowledge_0):
print "Your software does <b>not</b> embed 0-knowledge. \
This interface is useless in this case</body></html>"
exit(0)
c = get_config() c = get_config()
parser = ConfigParser.ConfigParser() c.NotebookApp.password = passwd("{{ password }}")
parser.read(knowledge_0)
if not parser.has_section("jupyter_notebook"):
parser.add_section("jupyter_notebook")
if not parser.has_option("jupyter_notebook", "password") or \
parser.get("jupyter_notebook", "password") == "":
parser.set("jupyter_notebook", "password", random_password())
c.NotebookApp.password = passwd(parser.get("jupyter_notebook", "password"))
with open(knowledge_0, 'w') as file: os.environ['PATH'] = "{{ gcc_location }}/bin" + os.pathsep + os.environ['PATH']
parser.write(file) os.environ['PYTHONPATH'] = "{{ cythonplus_repository }}" + os.pathsep + os.environ['PYTHONPATH']
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
extends = extends =
buildout.hash.cfg buildout.hash.cfg
../../stack/slapos.cfg ../../stack/slapos.cfg
../../component/cythonplus/buildout.cfg
../../component/openssl/buildout.cfg ../../component/openssl/buildout.cfg
../../component/jupyter/buildout.cfg ../../component/jupyter/buildout.cfg
../../stack/monitor/buildout.cfg ../../stack/monitor/buildout.cfg
...@@ -9,7 +10,10 @@ parts += ...@@ -9,7 +10,10 @@ parts +=
slapos-cookbook slapos-cookbook
jupyter jupyter
jupyter-notebook-initialized-scripts jupyter-notebook-initialized-scripts
instance-jupyter-notebook instance
[python]
part = python3
[gcc] [gcc]
# Always build GCC for Fortran (see openblas). # Always build GCC for Fortran (see openblas).
...@@ -27,9 +31,6 @@ mode = 0644 ...@@ -27,9 +31,6 @@ mode = 0644
[jupyter-notebook-config] [jupyter-notebook-config]
<= download-file-base <= download-file-base
[jupyter-set-password]
<= download-file-base
[erp5-kernel] [erp5-kernel]
<= download-file-base <= download-file-base
...@@ -39,64 +40,55 @@ mode = 0644 ...@@ -39,64 +40,55 @@ mode = 0644
[custom-js] [custom-js]
<= download-file-base <= download-file-base
[instance-jupyter-notebook] [instance]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template
template = ${:_profile_base_location_}/${:filename} url = ${:_profile_base_location_}/${:filename}
rendered = ${buildout:directory}/template.cfg output = ${buildout:directory}/template.cfg
mode = 0644 mode = 0644
context =
key bin_directory buildout:bin-directory
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
key openssl_output openssl-output:openssl
key python_executable jupyter:python_executable
key jupyter_config_location jupyter-notebook-config:location
key jupyter_config_filename jupyter-notebook-config:filename
key jupyter_set_password_location jupyter-set-password:location
key jupyter_set_password_filename jupyter-set-password:filename
key erp5_kernel_location erp5-kernel:location
key erp5_kernel_filename erp5-kernel:filename
key kernel_json_location kernel-json:location
key kernel_json_filename kernel-json:filename
key custom_js_location custom-js:location
key custom_js_filename custom-js:filename
key monitor_template_rendered buildout:directory
[versions] [versions]
Pygments = 2.2.0 Pygments = 2.7.2
astor = 0.5 astor = 0.5
async-generator = 1.10
backports-abc = 0.5 backports-abc = 0.5
backports.functools-lru-cache = 1.6.1 backports.functools-lru-cache = 1.6.1
backports.shutil-get-terminal-size = 1.0.0 backports.shutil-get-terminal-size = 1.0.0
bleach = 3.2.1
cycler = 0.10.0 cycler = 0.10.0
ipykernel = 4.5.2 defusedxml = 0.6.0
entrypoints = 0.3
ipykernel = 5.3.4
ipython = 5.3.0 ipython = 5.3.0
ipython-genutils = 0.1.0 ipython-genutils = 0.1.0
ipywidgets = 6.0.0 ipywidgets = 6.0.0
jupyter-client = 5.0.0 jupyter-client = 6.1.7
jupyter-core = 4.3.0 jupyter-core = 4.7.0
jupyterlab = 0.26.3 jupyterlab = 0.26.3
jupyterlab-launcher = 0.3.1 jupyterlab-launcher = 0.3.1
jupyterlab-pygments = 0.1.2
matplotlib = 2.1.2 matplotlib = 2.1.2
mistune = 0.7.3 mistune = 0.8.4
nbformat = 4.3.0 nest-asyncio = 1.4.3
notebook = 4.4.1 nbclient = 0.5.1
pandas = 0.19.2 nbformat = 5.0.8
notebook = 6.1.5
numpy = 1.14.6
pandas = 0.25.3
pandocfilters = 1.4.3
plone.recipe.command = 1.1 plone.recipe.command = 1.1
prompt-toolkit = 1.0.13 prompt-toolkit = 1.0.13
ptyprocess = 0.5.1 ptyprocess = 0.5.1
pyzmq = 16.0.2 pyzmq = 20.0.0
scikit-learn = 0.18.1 scikit-learn = 0.20.4
seaborn = 0.7.1 seaborn = 0.7.1
simplegeneric = 0.8.1 simplegeneric = 0.8.1
slapos.recipe.template = 4.4 statsmodels = 0.11.1
statsmodels = 0.8.0 testpath = 0.4.4
terminado = 0.6 terminado = 0.9.1
tornado = 4.4.2 tornado = 6.1
traitlets = 4.3.2 traitlets = 5.0.5
webencodings = 0.5.1
widgetsnbextension = 2.0.0 widgetsnbextension = 2.0.0
# numpy >= 1.13.1 is required for numpy.core.multiarray
numpy = 1.13.1
# Required by: # Required by:
...@@ -104,41 +96,55 @@ numpy = 1.13.1 ...@@ -104,41 +96,55 @@ numpy = 1.13.1
certifi = 2020.6.20 certifi = 2020.6.20
# Required by: # Required by:
# notebook==4.3.2 # notebook==6.1.5
# nbconvert 4.2.0 depends on entrypoints egg that is not available as tar/zip source. Send2Trash = 1.5.0
nbconvert = 4.1.0
# Required by:
# notebook==6.1.5
argon2-cffi = 20.1.0
# Required by:
# notebook==6.1.5
nbconvert = 6.0.7
# Required by: # Required by:
# ipython==5.3.0 # ipython==5.3.0
pathlib2 = 2.2.1 pathlib2 = 2.2.1
# Required by: # Required by:
# statsmodels==0.8.0 # statsmodels==0.11.1
patsy = 0.4.1 patsy = 0.5.1
# Required by: # Required by:
# ipython==5.3.0 # ipython==5.3.0
pexpect = 4.2.1 pexpect = 4.8.0
# Required by: # Required by:
# ipython==5.3.0 # ipython==5.3.0
pickleshare = 0.7.4 pickleshare = 0.7.4
# Required by: # Required by:
# matplotlib==2.1.2 # notebook==6.1.5
# pandas==0.19.2 prometheus-client = 0.9.0
python-dateutil = 2.6.0
# Required by:
# statsmodels==0.11.1
python-dateutil = 2.8.1
# Required by: # Required by:
# pathlib2==2.2.1 # pathlib2==2.2.1
scandir = 1.5 scandir = 1.5
# Required by: # Required by:
# statsmodels==0.8.0 # statsmodels==0.11.1
scipy = 0.19.0 pytz = 2020.4
# Required by: # Required by:
# tornado==4.4.2 # statsmodels==0.11.1
scipy = 1.0.1
# Required by:
# tornado==6.1
singledispatch = 3.4.0.3 singledispatch = 3.4.0.3
# Required by: # Required by:
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
############################################################################## ##############################################################################
import httplib import http.client
import json import json
import os import os
import requests import requests
...@@ -48,10 +48,14 @@ class TestJupyter(InstanceTestCase): ...@@ -48,10 +48,14 @@ class TestJupyter(InstanceTestCase):
except Exception as e: except Exception as e:
self.fail("Can't parse json in %s, error %s" % (parameter_dict['_'], e)) self.fail("Can't parse json in %s, error %s" % (parameter_dict['_'], e))
self.assertTrue('password' in connection_dict)
password = connection_dict['password']
self.assertEqual( self.assertEqual(
{ {
'jupyter-classic-url': 'https://[%s]:8888/tree' % (self._ipv6_address, ), 'jupyter-classic-url': 'https://[%s]:8888/tree' % (self._ipv6_address, ),
'jupyterlab-url': 'https://[%s]:8888/lab' % (self._ipv6_address, ), 'jupyterlab-url': 'https://[%s]:8888/lab' % (self._ipv6_address, ),
'password': '%s' % (password, ),
'url': 'https://[%s]:8888/tree' % (self._ipv6_address, ) 'url': 'https://[%s]:8888/tree' % (self._ipv6_address, )
}, },
connection_dict connection_dict
...@@ -60,7 +64,7 @@ class TestJupyter(InstanceTestCase): ...@@ -60,7 +64,7 @@ class TestJupyter(InstanceTestCase):
result = requests.get( result = requests.get(
connection_dict['url'], verify=False, allow_redirects=False) connection_dict['url'], verify=False, allow_redirects=False)
self.assertEqual( self.assertEqual(
[httplib.FOUND, True, '/login?next=%2Ftree'], [http.client.FOUND, True, '/login?next=%2Ftree'],
[result.status_code, result.is_redirect, result.headers['Location']] [result.status_code, result.is_redirect, result.headers['Location']]
) )
...@@ -68,7 +72,7 @@ class TestJupyter(InstanceTestCase): ...@@ -68,7 +72,7 @@ class TestJupyter(InstanceTestCase):
connection_dict['jupyter-classic-url'], connection_dict['jupyter-classic-url'],
verify=False, allow_redirects=False) verify=False, allow_redirects=False)
self.assertEqual( self.assertEqual(
[httplib.FOUND, True, '/login?next=%2Ftree'], [http.client.FOUND, True, '/login?next=%2Ftree'],
[result.status_code, result.is_redirect, result.headers['Location']] [result.status_code, result.is_redirect, result.headers['Location']]
) )
...@@ -76,6 +80,92 @@ class TestJupyter(InstanceTestCase): ...@@ -76,6 +80,92 @@ class TestJupyter(InstanceTestCase):
connection_dict['jupyterlab-url'], connection_dict['jupyterlab-url'],
verify=False, allow_redirects=False) verify=False, allow_redirects=False)
self.assertEqual( self.assertEqual(
[httplib.FOUND, True, '/login?next=%2Flab'], [http.client.FOUND, True, '/login?next=%2Flab'],
[result.status_code, result.is_redirect, result.headers['Location']]
)
class TestJupyterPassword(InstanceTestCase):
def test(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
self.assertTrue('_' in parameter_dict)
try:
connection_dict = json.loads(parameter_dict['_'])
except Exception as e:
self.fail("Can't parse json in %s, error %s" % (parameter_dict['_'], e))
url = connection_dict['url']
with requests.Session() as s:
resp = s.get(url, verify=False)
result = s.post(
resp.url,
verify = False,
data={"_xsrf": s.cookies["_xsrf"], "password": connection_dict['password']}
)
self.assertEqual(
[http.client.OK, url],
[result.status_code, result.url]
)
class TestJupyterAdditional(InstanceTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {
'frontend-additional-instance-guid': 'SOMETHING'
}
def test(self):
parameter_dict = self.computer_partition.getConnectionParameterDict()
self.assertTrue('_' in parameter_dict)
try:
connection_dict = json.loads(parameter_dict['_'])
except Exception as e:
self.fail("Can't parse json in %s, error %s" % (parameter_dict['_'], e))
result = requests.get(
connection_dict['url'], verify=False, allow_redirects=False)
self.assertEqual(
[http.client.FOUND, True, '/login?next=%2Ftree'],
[result.status_code, result.is_redirect, result.headers['Location']]
)
result = requests.get(
connection_dict['jupyter-classic-url'],
verify=False, allow_redirects=False)
self.assertEqual(
[http.client.FOUND, True, '/login?next=%2Ftree'],
[result.status_code, result.is_redirect, result.headers['Location']]
)
result = requests.get(
connection_dict['jupyterlab-url'],
verify=False, allow_redirects=False)
self.assertEqual(
[http.client.FOUND, True, '/login?next=%2Flab'],
[result.status_code, result.is_redirect, result.headers['Location']]
)
result = requests.get(
connection_dict['url-additional'], verify=False, allow_redirects=False)
self.assertEqual(
[http.client.FOUND, True, '/login?next=%2Ftree'],
[result.status_code, result.is_redirect, result.headers['Location']]
)
result = requests.get(
connection_dict['jupyter-classic-url-additional'],
verify=False, allow_redirects=False)
self.assertEqual(
[http.client.FOUND, True, '/login?next=%2Ftree'],
[result.status_code, result.is_redirect, result.headers['Location']]
)
result = requests.get(
connection_dict['jupyterlab-url-additional'],
verify=False, allow_redirects=False)
self.assertEqual(
[http.client.FOUND, True, '/login?next=%2Flab'],
[result.status_code, result.is_redirect, result.headers['Location']] [result.status_code, result.is_redirect, result.headers['Location']]
) )
...@@ -205,5 +205,4 @@ websockify = 0.9.0 ...@@ -205,5 +205,4 @@ websockify = 0.9.0
collective.recipe.environment = 0.2.0 collective.recipe.environment = 0.2.0
gitdb = 0.6.4 gitdb = 0.6.4
pycurl = 7.43.0 pycurl = 7.43.0
slapos.recipe.template = 4.4
smmap = 0.9.0 smmap = 0.9.0
...@@ -24,6 +24,3 @@ md5sum = 0a5e780dcf7d9ffe73f1ed789f863a57 ...@@ -24,6 +24,3 @@ md5sum = 0a5e780dcf7d9ffe73f1ed789f863a57
recipe = slapos.recipe.template recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename} url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/instance.cfg output = ${buildout:directory}/instance.cfg
[versions]
slapos.recipe.template = 4.4
...@@ -76,7 +76,6 @@ eggs += ...@@ -76,7 +76,6 @@ eggs +=
scripts = scripts =
[versions] [versions]
slapos.recipe.template = 4.4
surykatka = 0.5.0 surykatka = 0.5.0
......
...@@ -45,4 +45,3 @@ mode = 0644 ...@@ -45,4 +45,3 @@ mode = 0644
[versions] [versions]
rdiff-backup = 1.0.5+SlapOSPatched001 rdiff-backup = 1.0.5+SlapOSPatched001
slapos.recipe.template = 2.2
...@@ -67,6 +67,3 @@ dependencies = ...@@ -67,6 +67,3 @@ dependencies =
libexpat libexpat
libaio libaio
boost-lib boost-lib
[versions]
slapos.recipe.template = 4.4
...@@ -146,7 +146,6 @@ persistent = 4.6.4 ...@@ -146,7 +146,6 @@ persistent = 4.6.4
pycrypto = 2.6.1 pycrypto = 2.6.1
pycurl = 7.43.0 pycurl = 7.43.0
setproctitle = 1.1.10 setproctitle = 1.1.10
slapos.recipe.template = 4.4
transaction = 1.7.0 transaction = 1.7.0
zodbpickle = 1.0.4 zodbpickle = 1.0.4
cython-zstd = 0.2 cython-zstd = 0.2
......
...@@ -84,6 +84,3 @@ packages += ...@@ -84,6 +84,3 @@ packages +=
libnetfilter-queue-dev nftables libnetfilter-queue-dev nftables
# extra requirements for this SR # extra requirements for this SR
screen xz-utils screen xz-utils
[versions]
slapos.recipe.template = 4.4
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# list of go git repositories to fetch # list of go git repositories to fetch
[gowork.goinstall] [gowork.goinstall]
depends_gitfetch = depends_gitfetch =
${go_crawshaw.io_sqlite:recipe}
${go_github.com_DataDog_czlib:recipe} ${go_github.com_DataDog_czlib:recipe}
${go_github.com_cznic_strutil:recipe} ${go_github.com_cznic_strutil:recipe}
${go_github.com_davecgh_go-spew:recipe} ${go_github.com_davecgh_go-spew:recipe}
...@@ -37,6 +38,12 @@ depends_gitfetch = ...@@ -37,6 +38,12 @@ depends_gitfetch =
${go_lab.nexedi.com_kirr_neo:recipe} ${go_lab.nexedi.com_kirr_neo:recipe}
[go_crawshaw.io_sqlite]
<= go-git-package
go.importpath = crawshaw.io/sqlite
repository = https://github.com/crawshaw/sqlite
revision = v0.3.2-7-gc582b9de4f
[go_github.com_DataDog_czlib] [go_github.com_DataDog_czlib]
<= go-git-package <= go-git-package
go.importpath = github.com/DataDog/czlib go.importpath = github.com/DataDog/czlib
...@@ -221,10 +228,10 @@ revision = v2.1.1-97-geeeca48fe7 ...@@ -221,10 +228,10 @@ revision = v2.1.1-97-geeeca48fe7
<= go-git-package <= go-git-package
go.importpath = lab.nexedi.com/kirr/go123 go.importpath = lab.nexedi.com/kirr/go123
repository = https://lab.nexedi.com/kirr/go123.git repository = https://lab.nexedi.com/kirr/go123.git
revision = 316617668e revision = c8d9907ef7
[go_lab.nexedi.com_kirr_neo] [go_lab.nexedi.com_kirr_neo]
<= go-git-package <= go-git-package
go.importpath = lab.nexedi.com/kirr/neo go.importpath = lab.nexedi.com/kirr/neo
repository = https://lab.nexedi.com/kirr/neo.git repository = https://lab.nexedi.com/kirr/neo.git
revision = v1.9-2480-g5ee3c077b3 revision = v1.12-2791-gf3effa6c53
...@@ -34,7 +34,7 @@ parts = ...@@ -34,7 +34,7 @@ parts =
neoppod-develop neoppod-develop
neoppod neoppod
wendelin.core-dev wendelin.core
scripts scripts
# for ZEO scripts (runzeo) # for ZEO scripts (runzeo)
...@@ -107,7 +107,7 @@ template = inline: ...@@ -107,7 +107,7 @@ template = inline:
[neotest-python] [neotest-python]
<= python-interpreter <= python-interpreter
eggs += eggs +=
${wendelin.core-dev:egg} ${wendelin.core:egg}
${neoppod:eggs} ${neoppod:eggs}
# for instance # for instance
plone.recipe.command plone.recipe.command
...@@ -116,7 +116,7 @@ eggs += ...@@ -116,7 +116,7 @@ eggs +=
recipe = zc.recipe.egg:scripts recipe = zc.recipe.egg:scripts
eggs = eggs =
# to install not only wendelin.core modules but also scripts # to install not only wendelin.core modules but also scripts
${wendelin.core-dev:egg} ${wendelin.core:egg}
# wendelin.core: latest not yet released # wendelin.core: latest not yet released
......
...@@ -42,5 +42,4 @@ output = ${buildout:directory}/instance-nginx.cfg.in ...@@ -42,5 +42,4 @@ output = ${buildout:directory}/instance-nginx.cfg.in
mode = 0644 mode = 0644
[versions] [versions]
slapos.recipe.template = 4.4
inotifyx = 0.2.2 inotifyx = 0.2.2
...@@ -32,7 +32,3 @@ output = ${buildout:directory}/${:_buildout_section_name_} ...@@ -32,7 +32,3 @@ output = ${buildout:directory}/${:_buildout_section_name_}
recipe = slapos.recipe.build:download recipe = slapos.recipe.build:download
url = https://sourceforge.net/projects/plantuml/files/1.2020.15/plantuml.1.2020.15.war url = https://sourceforge.net/projects/plantuml/files/1.2020.15/plantuml.1.2020.15.war
md5sum = ed203cb3b90df8f77492fa36ea6490a5 md5sum = ed203cb3b90df8f77492fa36ea6490a5
[versions]
slapos.recipe.template = 4.4
...@@ -19,6 +19,3 @@ url = ${:_profile_base_location_}/instance.cfg.in ...@@ -19,6 +19,3 @@ url = ${:_profile_base_location_}/instance.cfg.in
output = ${buildout:directory}/instance.cfg output = ${buildout:directory}/instance.cfg
md5sum = d8b833a2054b82b6031a9420008b58fd md5sum = d8b833a2054b82b6031a9420008b58fd
mode = 0644 mode = 0644
[versions]
slapos.recipe.template = 2.4.2
...@@ -26,7 +26,7 @@ md5sum = 20c37ea06a8fa405bc02470d5115fd11 ...@@ -26,7 +26,7 @@ md5sum = 20c37ea06a8fa405bc02470d5115fd11
[template-dns-replicate] [template-dns-replicate]
_update_hash_filename_ = instance-powerdns-replicate.cfg.jinja2 _update_hash_filename_ = instance-powerdns-replicate.cfg.jinja2
md5sum = c2bd424f588ad57d37f4cf1329734fb6 md5sum = 72ce30bee3b8a9da8ac9be7eb65d83a2
[iso-list] [iso-list]
_update_hash_filename_ = template/zz.countries.nexedi.dk.rbldnsd _update_hash_filename_ = template/zz.countries.nexedi.dk.rbldnsd
...@@ -34,4 +34,4 @@ md5sum = c4dc8c141d81b92d92cdb82ca67a13ee ...@@ -34,4 +34,4 @@ md5sum = c4dc8c141d81b92d92cdb82ca67a13ee
[template-zones-file] [template-zones-file]
_update_hash_filename_ = template/zones-file.yml.jinja2 _update_hash_filename_ = template/zones-file.yml.jinja2
md5sum = 03037141ad1d3467ae878c9798724f70 md5sum = 612de569ac3d1e8cc10b830683ff92ae
...@@ -33,12 +33,12 @@ ...@@ -33,12 +33,12 @@
"default": "", "default": "",
"type": "string" "type": "string"
}, },
"zone": { "supported-zone-list": {
"title": "Zone", "title": "Zone",
"description": "Zone to be handled by the DNS cluster", "description": "Zone to be handled by the DNS cluster",
"type": "string", "type": "string",
"default": "domain.com", "default": "domain.com",
"pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$" "pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}(\\s([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6})*$"
}, },
"server-admin": { "server-admin": {
"title": "Zone Administrator Email", "title": "Zone Administrator Email",
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
"title": "DNS domains template string", "title": "DNS domains template string",
"description": "Template used to generate DNS domain name", "description": "Template used to generate DNS domain name",
"type": "string", "type": "string",
"default": "ns%s. + zone" "default": "ns%s.domain.com"
}, },
"monitor-interface-url": { "monitor-interface-url": {
"title": "Monitor Web Interface URL", "title": "Monitor Web Interface URL",
......
...@@ -33,9 +33,9 @@ context = ...@@ -33,9 +33,9 @@ context =
{% endif -%} {% endif -%}
## DNS set up ## DNS set up
{% set zone = slapparameter_dict.pop('zone', 'domain.com') %} {%- set supported_zone_list = slapparameter_dict.pop('supported-zone-list', 'domain.com').split() %}
{% set server_admin = slapparameter_dict.pop('server-admin', 'admin@domain.com') %} {% set server_admin = slapparameter_dict.pop('server-admin', 'admin@domain.com') %}
{% set dns_name_template_string = slapparameter_dict.pop('dns-name-template-string', 'ns%s.' + zone) %} {% set dns_name_template_string = slapparameter_dict.pop('dns-name-template-string', 'ns%s.domain.com') %}
# Here we request individualy each dns. # Here we request individualy each dns.
# The presence of sla parameters is checked and added if found # The presence of sla parameters is checked and added if found
...@@ -65,7 +65,7 @@ name = {{dns_name}} ...@@ -65,7 +65,7 @@ name = {{dns_name}}
{% if state_key in slapparameter_dict %} {% if state_key in slapparameter_dict %}
state = {{ slapparameter_dict.pop(state_key) }} state = {{ slapparameter_dict.pop(state_key) }}
{% endif%} {% endif%}
config-zone = {{ zone }} config-supported-zone-list = {{ ' '.join(supported_zone_list) }}
config-soa = {{ "%s,%s" % (dns_domain, server_admin) }} config-soa = {{ "%s,%s" % (dns_domain, server_admin) }}
{% for parameter in sla_parameters -%} {% for parameter in sla_parameters -%}
sla-{{ parameter }} = {{ slapparameter_dict.pop( sla_key + parameter ) }} sla-{{ parameter }} = {{ slapparameter_dict.pop( sla_key + parameter ) }}
...@@ -74,11 +74,9 @@ sla-{{ parameter }} = {{ slapparameter_dict.pop( sla_key + parameter ) }} ...@@ -74,11 +74,9 @@ sla-{{ parameter }} = {{ slapparameter_dict.pop( sla_key + parameter ) }}
[{{promise_section_title}}] [{{promise_section_title}}]
<= monitor-promise-base <= monitor-promise-base
module = check_port_listening module = check_port_listening
name = pdns-port-listening.py name = {{promise_section_title}}.py
{% set ipv6 = '${' ~ request_section_title ~ ':connection-powerdns-ipv6}' -%} config-hostname = {{ '${' ~ request_section_title ~ ':connection-powerdns-ipv6}' }}
config-hostname = {{ipv6}} config-port = {{ '${' ~ request_section_title ~ ':connection-powerdns-port}' }}
{% set port = '${' ~ request_section_title ~ ':connection-powerdns-port}' -%}
config-port = {{port}}
{% do monitor_url_list.append('${' ~ request_section_title ~ ':connection-monitor-base-url}') -%} {% do monitor_url_list.append('${' ~ request_section_title ~ ':connection-monitor-base-url}') -%}
{% endfor -%} {% endfor -%}
......
...@@ -8,6 +8,13 @@ ...@@ -8,6 +8,13 @@
"description": "Record for the configuration", "description": "Record for the configuration",
"type": "string" "type": "string"
}, },
"applicable-zone": {
"title": "Applicable Zone",
"description": "Zone to which this record belongs. You can put only one zone here. If the record belongs to several zones, you should create several slaves.",
"pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$",
"default": "domain.com",
"type": "string"
},
"origin": { "origin": {
"title": "Origin", "title": "Origin",
"description": "Used to qualify RR in the configuration. i.e.: if your origin is a.example.com and the RR for Europe is 'eu' the european clients will use eu.a.example.com", "description": "Used to qualify RR in the configuration. i.e.: if your origin is a.example.com and the RR for Europe is 'eu' the european clients will use eu.a.example.com",
......
...@@ -54,7 +54,6 @@ mode = 0644 ...@@ -54,7 +54,6 @@ mode = 0644
PyRSS2Gen = 1.1 PyRSS2Gen = 1.1
cns.recipe.symlink = 0.2.3 cns.recipe.symlink = 0.2.3
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 4.4
passlib = 1.7.1 passlib = 1.7.1
GitPython = 2.1.11 GitPython = 2.1.11
lockfile = 0.12.2 lockfile = 0.12.2
......
# See https://doc.powerdns.com/authoritative/backends/geoip.html # See https://doc.powerdns.com/authoritative/backends/geoip.html
{%- set slave_instance_list = json_module.loads(slapparameter_dict.get('extra_slave_instance_list', '[]')) %} {%- set slave_instance_list = json_module.loads(slapparameter_dict.get('extra_slave_instance_list', '[]')) %}
{%- set zone = slapparameter_dict.get('zone', 'example.com') %} {%- set supported_zone_list = slapparameter_dict.get('supported-zone-list', 'example.com').split() %}
{%- macro disambiguate_domain_name(a, b) %} {%- macro disambiguate_domain_name(a, b) %}
{#- See http://www.dns-sd.org/trailingdotsindomainnames.html #} {#- See http://www.dns-sd.org/trailingdotsindomainnames.html #}
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
{%- endmacro %} {%- endmacro %}
domains: domains:
{%- for zone in supported_zone_list %}
- domain: {{ zone }} - domain: {{ zone }}
# TODO: what value for ttl? # TODO: what value for ttl?
ttl: 300 ttl: 300
...@@ -48,6 +50,7 @@ domains: ...@@ -48,6 +50,7 @@ domains:
{%- for slave in slave_instance_list %} {%- for slave in slave_instance_list %}
{%- if slave['applicable-zone'] == zone %}
{%- set origin = slave['origin'] %} {%- set origin = slave['origin'] %}
{%- set unique_slave_id = slave['slave_reference'] %} {%- set unique_slave_id = slave['slave_reference'] %}
{#- Set the RR to use for each region, as described in {#- Set the RR to use for each region, as described in
...@@ -77,13 +80,15 @@ domains: ...@@ -77,13 +80,15 @@ domains:
- cname: {{ disambiguate_domain_name(rr_dict[region], origin) }} - cname: {{ disambiguate_domain_name(rr_dict[region], origin) }}
{%- endfor %} {%- endfor %}
{%- endfor %} {%- endfor %}
{%- endif %}
{%- endfor %} {%- endfor %}
services: services:
{%- for slave in slave_instance_list %} {%- for slave in slave_instance_list %}
{%- if slave['applicable-zone'] == zone %}
{%- set origin = slave['origin'] %} {%- set origin = slave['origin'] %}
{%- set unique_slave_id = slave['slave_reference'] %} {%- set unique_slave_id = slave['slave_reference'] %}
{{ disambiguate_domain_name(slave['record'], zone) }}: {{ disambiguate_domain_name(slave['record'], slave['applicable-zone']) }}:
{#- Note: Placeholders (i.e. "country." and "continent.") are used to avoid {#- Note: Placeholders (i.e. "country." and "continent.") are used to avoid
possible name collisions, e.g.: possible name collisions, e.g.:
- %cc for American Samoa is 'as' - %cc for American Samoa is 'as'
...@@ -94,4 +99,6 @@ domains: ...@@ -94,4 +99,6 @@ domains:
{%- for ip_range, country_code in china %} {%- for ip_range, country_code in china %}
{{ ip_range }}: {{ country_code }}.country.{{ unique_slave_id }} {{ ip_range }}: {{ country_code }}.country.{{ unique_slave_id }}
{%- endfor %} {%- endfor %}
{%- endif %}
{%- endfor %} {%- endfor %}
{%- endfor %}
...@@ -31,11 +31,14 @@ import dns.query ...@@ -31,11 +31,14 @@ import dns.query
import http.client import http.client
import os import os
import requests import requests
import unittest
from slapos.recipe.librecipe import generateHashFromFiles from slapos.recipe.librecipe import generateHashFromFiles
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
skip = unittest.skip('port conflit between powerdns instances')
setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass( setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath( os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software.cfg'))) os.path.join(os.path.dirname(__file__), '..', 'software.cfg')))
...@@ -59,42 +62,40 @@ WEST_ASIAN_SUBNET = '46.70.0.0' ...@@ -59,42 +62,40 @@ WEST_ASIAN_SUBNET = '46.70.0.0'
class PowerDNSTestCase(SlapOSInstanceTestCase): class PowerDNSTestCase(SlapOSInstanceTestCase):
# power dns uses sockets and need shorter paths on test nodes. # power dns uses sockets and need shorter paths on test nodes.
__partition_reference__ = 'pdns' __partition_reference__ = 'pdns'
default_zone = 'domain.com' default_supported_zone = 'domain.com'
# focus to test connexion parameters only depending on PowerDNS # focus to test connexion parameters only depending on PowerDNS
def getPowerDNSParameterDict(self, parameter_dict): def getPowerDNSParameterDict(self, parameter_dict, dns_quantity):
new_parameter_dict = {} selected_key_list = ['ns-record', ]
for key, value in parameter_dict.items(): for replicate_nb in range(1, dns_quantity + 1):
if key in [ selected_key_list.append('ns%s-port' % replicate_nb)
'ns-record', selected_key_list.append('ns%s-ipv6' % replicate_nb)
'ns1-port', selected_key_list.append('slave-amount')
'ns1-ipv6',
'slave-amount', return {
]: k: v for k, v in parameter_dict.items() if k in selected_key_list
new_parameter_dict[key] = value }
return new_parameter_dict
def getPowerDNSConnexionParameterDict(self, dns_quantity=1):
def getPowerDNSConnexionParameterDict(self):
return self.getPowerDNSParameterDict( return self.getPowerDNSParameterDict(
self.requestDefaultInstance().getConnectionParameterDict() self.requestDefaultInstance().getConnectionParameterDict(),
dns_quantity
) )
def _test_parameter_dict(self, zone=None, dns_quantity=1, slave_amount=0): def _test_parameter_dict(self, dns_quantity=1, slave_amount=0):
if zone is None:
zone = self.default_zone
parameter_dict = self.getPowerDNSConnexionParameterDict() parameter_dict = self.getPowerDNSConnexionParameterDict()
expected_dict = { expected_dict = {
'ns-record': '', 'ns-record': '',
} }
ns_record = '' ns_record = []
for replicate_nb in range(1, dns_quantity + 1): for replicate_nb in range(1, dns_quantity + 1):
prefix = 'ns%s' % replicate_nb ns_id = 'ns%s' % replicate_nb
ns_record += prefix + '.%s' % zone ns_record.append(ns_id + '.' + self.default_supported_zone)
expected_dict[prefix + '-port'] = str(DNS_PORT) expected_dict[ns_id + '-port'] = str(DNS_PORT)
expected_dict[prefix + '-ipv6'] = self._ipv6_address expected_dict[ns_id + '-ipv6'] = self._ipv6_address
expected_dict['ns-record'] = ns_record expected_dict['ns-record'] = ','.join(ns_record)
expected_dict['slave-amount'] = str(slave_amount) expected_dict['slave-amount'] = str(slave_amount)
self.assertEqual(expected_dict, parameter_dict) self.assertEqual(expected_dict, parameter_dict)
...@@ -149,24 +150,11 @@ class TestMasterRequest(PowerDNSTestCase): ...@@ -149,24 +150,11 @@ class TestMasterRequest(PowerDNSTestCase):
self._test_parameter_dict() self._test_parameter_dict()
class TestMasterRequestDomain(PowerDNSTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {
'zone': 'toto.example.com',
}
def test(self):
self._test_parameter_dict(zone=self.getInstanceParameterDict()['zone'])
class PowerDNSSlaveTestCase(PowerDNSTestCase): class PowerDNSSlaveTestCase(PowerDNSTestCase):
@classmethod @classmethod
def requestDefaultInstance(cls): def requestDefaultInstance(cls, state='started'):
default_instance = super(PowerDNSSlaveTestCase, cls)\ default_instance = super().requestDefaultInstance(state=state)
.requestDefaultInstance()
cls.requestSlaves() cls.requestSlaves()
return default_instance return default_instance
...@@ -202,49 +190,19 @@ class PowerDNSSlaveTestCase(PowerDNSTestCase): ...@@ -202,49 +190,19 @@ class PowerDNSSlaveTestCase(PowerDNSTestCase):
).getConnectionParameterDict()) ).getConnectionParameterDict())
return parameter_dict_list return parameter_dict_list
@classmethod
def getSlaveParameterDictDict(cls):
return {
'slave-pdns1': {
'record': 'test1',
'origin': 'nexedi.com',
'default': 'test1.com.',
'africa': 'test1africa.com.',
'china-telecom': 'test1china-telecom.com.',
'china-unicom': 'test1china-unicom.com.',
'china-mobile': 'test1china-mobile.com.',
'east-asia': 'test1east-asia.com.',
'europe': 'test1europe.com.',
'hong-kong': 'test1hong-kong.com.',
'japan': 'test1japan.com.',
'north-america': 'test1north-america.com.',
'oceania': 'test1oceania.com.',
'south-america': 'test1south-america.com.',
'west-asia': 'test1west-asia.com.',
},
'slave-pdns2': {
'record': 'test2',
'origin': 'nexedi.com',
'default': 'test2.com.',
'china-telecom': 'test2china-telecom.com.',
'europe': 'test2europe.com.',
'japan': 'test2japan.com.',
}
}
def dns_query(self, domain_name, subnet): def dns_query(self, domain_name, subnet):
message = dns.message.make_query(domain_name, 'A') message = dns.message.make_query(domain_name, 'A')
client_subnet_option = dns.edns.ECSOption(subnet) client_subnet_option = dns.edns.ECSOption(subnet)
message.use_edns(options=[client_subnet_option]) message.use_edns(options=[client_subnet_option])
answer = dns.query.udp(message, self._ipv6_address, port=DNS_PORT) answer = dns.query.udp(message, self._ipv6_address, port=DNS_PORT)
return answer.find_rrset( return answer.get_rrset(
dns.message.ANSWER, dns.message.ANSWER,
dns.name.from_text(domain_name), dns.name.from_text(domain_name),
dns.rdataclass.IN, dns.rdataclass.IN,
dns.rdatatype.CNAME dns.rdatatype.CNAME
).to_text().split()[-1] ).to_text().split()[-1]
def _test_dns_resolver(self, zone): def _test_dns_resolver(self):
slave_parameter_dict_dict = self.getSlaveParameterDictDict() slave_parameter_dict_dict = self.getSlaveParameterDictDict()
subnet_dict = { subnet_dict = {
'africa': AFRICAN_SUBNET, 'africa': AFRICAN_SUBNET,
...@@ -277,39 +235,195 @@ class PowerDNSSlaveTestCase(PowerDNSTestCase): ...@@ -277,39 +235,195 @@ class PowerDNSSlaveTestCase(PowerDNSTestCase):
for slave_name in slave_parameter_dict_dict: for slave_name in slave_parameter_dict_dict:
slave_parameter_dict = slave_parameter_dict_dict[slave_name] slave_parameter_dict = slave_parameter_dict_dict[slave_name]
domain_name = '%s.%s' % (slave_parameter_dict['record'], zone) domain_name = '%s.%s' % (
slave_parameter_dict['record'], slave_parameter_dict['applicable-zone']
)
for region in subnet_dict: for region in subnet_dict:
self.assertEqual( self.assertEqual(
slave_parameter_dict.pop( slave_parameter_dict.get(
region, region,
'%s.%s.' % (default_rr_dict[region], slave_parameter_dict['origin']) '%s.%s.' % (default_rr_dict[region], slave_parameter_dict['origin'])
), ),
self.dns_query(domain_name, subnet_dict[region]) self.dns_query(domain_name, subnet_dict[region])
) )
def _test(self, zone=None): def _test_slaves(self, dns_quantity=1):
if zone is None:
zone = self.default_zone
self._test_parameter_dict( self._test_parameter_dict(
zone=zone, dns_quantity=dns_quantity,
slave_amount=len(self.getSlaveParameterDictDict()) slave_amount=len(self.getSlaveParameterDictDict())
) )
self._test_dns_resolver(zone) self._test_dns_resolver()
class TestSlaveRequest(PowerDNSSlaveTestCase): class TestSlaveRequest(PowerDNSSlaveTestCase):
@classmethod
def getSlaveParameterDictDict(cls):
return {
'slave-test1.domain.com': {
'record': 'test1',
'applicable-zone': 'domain.com',
'origin': 'nexedi.com',
'default': 'test1.com.',
'africa': 'test1africa.com.',
'china-telecom': 'test1china-telecom.com.',
'china-unicom': 'test1china-unicom.com.',
'china-mobile': 'test1china-mobile.com.',
'east-asia': 'test1east-asia.com.',
'europe': 'test1europe.com.',
'hong-kong': 'test1hong-kong.com.',
'japan': 'test1japan.com.',
'north-america': 'test1north-america.com.',
'oceania': 'test1oceania.com.',
'south-america': 'test1south-america.com.',
'west-asia': 'test1west-asia.com.',
},
'slave-test2.domain.com': {
'record': 'test2',
'applicable-zone': 'domain.com',
'origin': 'nexedi.com',
'default': 'test2.com.',
'china-telecom': 'test2china-telecom.com.',
'europe': 'test2europe.com.',
'japan': 'test2japan.com.',
},
}
def test(self): def test(self):
self._test() self._test_slaves()
class TestSlaveRequestDomain(PowerDNSSlaveTestCase): class TestSlaveRequestSingleDomain(TestSlaveRequest):
@classmethod
def getSlaveParameterDictDict(cls):
return {
'slave-test1.toto.example.com': {
'record': 'test1',
'applicable-zone': 'toto.example.com',
'origin': 'nexedi.com',
'default': 'test1.com.',
'africa': 'test1africa.com.',
'china-telecom': 'test1china-telecom.com.',
'china-unicom': 'test1china-unicom.com.',
'china-mobile': 'test1china-mobile.com.',
'east-asia': 'test1east-asia.com.',
'europe': 'test1europe.com.',
'hong-kong': 'test1hong-kong.com.',
'japan': 'test1japan.com.',
'north-america': 'test1north-america.com.',
'oceania': 'test1oceania.com.',
'south-america': 'test1south-america.com.',
'west-asia': 'test1west-asia.com.',
},
'slave-test2.toto.example.com': {
'record': 'test2',
'applicable-zone': 'toto.example.com',
'origin': 'nexedi.com',
'default': 'test2.com.',
'china-telecom': 'test2china-telecom.com.',
'europe': 'test2europe.com.',
'japan': 'test2japan.com.',
},
}
@classmethod
def getInstanceParameterDict(cls):
return {
'supported-zone-list': 'toto.example.com',
}
class TestSlaveRequestDomains(TestSlaveRequest):
@classmethod
def getSlaveParameterDictDict(cls):
return {
'slave-test1.toto.example.com': {
'record': 'test1',
'applicable-zone': 'toto.example.com',
'origin': 'nexedi.com',
'default': 'test1.com.',
'africa': 'test1africa.com.',
'china-telecom': 'test1china-telecom.com.',
'china-unicom': 'test1china-unicom.com.',
'china-mobile': 'test1china-mobile.com.',
'east-asia': 'test1east-asia.com.',
'europe': 'test1europe.com.',
'hong-kong': 'test1hong-kong.com.',
'japan': 'test1japan.com.',
'north-america': 'test1north-america.com.',
'oceania': 'test1oceania.com.',
'south-america': 'test1south-america.com.',
'west-asia': 'test1west-asia.com.',
},
'slave-test2.toto.example.com': {
'record': 'test2',
'applicable-zone': 'toto.example.com',
'origin': 'nexedi.com',
'default': 'test2.com.',
'china-telecom': 'test2china-telecom.com.',
'europe': 'test2europe.com.',
'japan': 'test2japan.com.',
},
'slave-test1.tata.example.com': {
'record': 'test1',
'applicable-zone': 'tata.example.com',
'origin': 'nexedi.com',
'default': 'test1.com.',
'china-telecom': 'test1china-telecom.com.',
'europe': 'test1europe.com.',
'japan': 'test1japan.com.',
},
'slave-test4.tata.example.com': {
'record': 'test4',
'applicable-zone': 'tata.example.com',
'origin': 'nexedi.com',
'default': 'test4".com.',
'africa': 'test4africa.com.',
'china-telecom': 'test4china-telecom.com.',
'china-unicom': 'test4china-unicom.com.',
'china-mobile': 'test4china-mobile.com.',
'east-asia': 'test4east-asia.com.',
'europe': 'test4europe.com.',
'hong-kong': 'test4hong-kong.com.',
'japan': 'test4japan.com.',
'north-america': 'test4north-america.com.',
'oceania': 'test4oceania.com.',
'south-america': 'test4south-america.com.',
'west-asia': 'test4west-asia.com.',
},
'slave-test5.tata.example.com': {
'record': 'test5',
'applicable-zone': 'tata.example.com',
'origin': 'nexedi.com',
'default': 'test5.com.',
'china-telecom': 'test5china-telecom.com.',
'europe': 'test5europe.com.',
'japan': 'test5japan.com.',
},
}
@classmethod @classmethod
def getInstanceParameterDict(cls): def getInstanceParameterDict(cls):
return { return {
'zone': 'toto.example.com', 'supported-zone-list': 'toto.example.com tata.example.com',
}
# Because all powerdns instances run under the same ip address during tests,
# there is a port conflict between these instances
@skip
class TestMultipleInstances(TestSlaveRequestDomains):
@classmethod
def getInstanceParameterDict(cls):
return {
'-dns-quantity': '2',
'supported-zone-list': 'toto.example.com tata.example.com',
} }
def test(self): def test(self):
self._test(zone=self.getInstanceParameterDict()['zone']) self._test_slaves(
dns_quantity=int(self.getInstanceParameterDict()['-dns-quantity'])
)
...@@ -46,5 +46,4 @@ context = ...@@ -46,5 +46,4 @@ context =
[versions] [versions]
collective.recipe.environment = 1.1.0 collective.recipe.environment = 1.1.0
collective.recipe.grp = 1.1.0 collective.recipe.grp = 1.1.0
slapos.recipe.template = 4.4
plone.recipe.command = 1.1 plone.recipe.command = 1.1
...@@ -34,7 +34,3 @@ context = ...@@ -34,7 +34,3 @@ context =
raw pureftpd_bin ${pure-ftpd:location}/sbin/pure-ftpd raw pureftpd_bin ${pure-ftpd:location}/sbin/pure-ftpd
raw pureuploadscript_bin ${pure-ftpd:location}/sbin/pure-uploadscript raw pureuploadscript_bin ${pure-ftpd:location}/sbin/pure-uploadscript
raw purepw_bin ${pure-ftpd:location}/bin/pure-pw raw purepw_bin ${pure-ftpd:location}/bin/pure-pw
[versions]
slapos.recipe.template = 4.4
...@@ -72,7 +72,6 @@ context = ...@@ -72,7 +72,6 @@ context =
[versions] [versions]
re6stnet = 0.551 re6stnet = 0.551
slapos.recipe.template = 4.4
# Required by: # Required by:
# re6stnet==0.533 # re6stnet==0.533
......
...@@ -26,4 +26,3 @@ mode = 0644 ...@@ -26,4 +26,3 @@ mode = 0644
[versions] [versions]
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 2.4.2
...@@ -149,7 +149,3 @@ link-binary = ...@@ -149,7 +149,3 @@ link-binary =
[proxy-need-start-stop.sh.in] [proxy-need-start-stop.sh.in]
<= download-file <= download-file
# Pin versions of eggs used that are not already pinned by stack/slapos.cfg
[versions]
slapos.recipe.template = 4.4
...@@ -56,4 +56,3 @@ output = ${buildout:directory}/template.cfg ...@@ -56,4 +56,3 @@ output = ${buildout:directory}/template.cfg
[versions] [versions]
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 4.4
...@@ -19,4 +19,4 @@ md5sum = c4ac5de141ae6a64848309af03e51d88 ...@@ -19,4 +19,4 @@ md5sum = c4ac5de141ae6a64848309af03e51d88
[template-selenium] [template-selenium]
filename = instance-selenium.cfg.in filename = instance-selenium.cfg.in
md5sum = 597991d7354970550d25324e3836adda md5sum = fc2e8176929063903a69b0e80007ca63
...@@ -224,7 +224,6 @@ template = inline: ...@@ -224,7 +224,6 @@ template = inline:
Port $${sshd-address:port} Port $${sshd-address:port}
ListenAddress $${sshd-address:ip} ListenAddress $${sshd-address:ip}
Protocol 2 Protocol 2
UsePrivilegeSeparation no
HostKey $${ssh-host-rsa-key:output} HostKey $${ssh-host-rsa-key:output}
HostKey $${ssh-host-dsa-key:output} HostKey $${ssh-host-dsa-key:output}
HostKey $${ssh-host-ecdsa-key:output} HostKey $${ssh-host-ecdsa-key:output}
......
...@@ -75,4 +75,3 @@ post-install = ...@@ -75,4 +75,3 @@ post-install =
[versions] [versions]
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.template = 4.4
...@@ -11,4 +11,3 @@ extends = common.cfg ...@@ -11,4 +11,3 @@ extends = common.cfg
Pygments = 1.6 Pygments = 1.6
collective.recipe.environment = 0.2.0 collective.recipe.environment = 0.2.0
collective.recipe.template = 1.10 collective.recipe.template = 1.10
slapos.recipe.template = 4.4
...@@ -23,3 +23,7 @@ md5sum = 4998e62351f54700ee23a2ca8cd89329 ...@@ -23,3 +23,7 @@ md5sum = 4998e62351f54700ee23a2ca8cd89329
[template-apache-backend-conf] [template-apache-backend-conf]
filename = apache-backend.conf.in filename = apache-backend.conf.in
md5sum = 9d7104ce18f79a7a84988efc11f5ed23 md5sum = 9d7104ce18f79a7a84988efc11f5ed23
[template-haproxy-cfg]
filename = haproxy.cfg.in
md5sum = fec6a312e4ef84b02837742992aaf495
{% set server_check_path = parameter_dict['server-check-path'] -%}
global
maxconn 4096
stats socket {{ parameter_dict['socket-path'] }} level admin
defaults
mode http
retries 1
option redispatch
maxconn 2000
cookie SERVERID rewrite
balance roundrobin
stats uri /haproxy
stats realm Global\ statistics
# it is useless to have timeout much bigger than the one of apache.
# By default apache use 300s, so we set slightly more in order to
# make sure that apache will first stop the connection.
timeout server 305s
# Stop waiting in queue for a zope to become available.
# If no zope can be reached after one minute, consider the request will
# never succeed.
timeout queue 60s
# The connection should be immediate on LAN,
# so we should not set more than 5 seconds, and it could be already too much
timeout connect 5s
# As requested in haproxy doc, make this "at least equal to timeout server".
timeout client 305s
# Use "option httpclose" to not preserve client & server persistent connections
# while handling every incoming request individually, dispatching them one after
# another to servers, in HTTP close mode. This is really needed when haproxy
# is configured with maxconn to 1, without this option browsers are unable
# to render a page
option httpclose
{% for name, (port, backend_list) in sorted(parameter_dict['backend-dict'].iteritems()) -%}
listen {{ name }}
bind {{ parameter_dict['ip'] }}:{{ port }}
http-request set-header X-Balancer-Current-Cookie SERVERID
{% set has_webdav = [] -%}
{% for address, connection_count, webdav in backend_list -%}
{% if webdav %}{% do has_webdav.append(None) %}{% endif -%}
{% set server_name = name ~ '-' ~ loop.index0 -%}
server {{ server_name }} {{ address }} cookie {{ server_name }} check inter 3s rise 1 fall 2 maxqueue 5 maxconn {{ connection_count }}
{% endfor -%}
{%- if not has_webdav and server_check_path %}
option httpchk GET {{ server_check_path }}
{% endif -%}
{% endfor %}
...@@ -63,7 +63,9 @@ filename = instance-balancer.cfg.in ...@@ -63,7 +63,9 @@ filename = instance-balancer.cfg.in
[template-apache-backend-conf] [template-apache-backend-conf]
url = ${:_profile_base_location_}/${:filename} url = ${:_profile_base_location_}/${:filename}
filename = apache-backend.conf.in
[template-haproxy-cfg]
url = ${:_profile_base_location_}/${:filename}
[versions] [versions]
python-memcached = 1.47 python-memcached = 1.47
......
...@@ -48,9 +48,9 @@ class TestPublishedURLIsReachableMixin(object): ...@@ -48,9 +48,9 @@ class TestPublishedURLIsReachableMixin(object):
"""Mixin that checks that default page of ERP5 is reachable. """Mixin that checks that default page of ERP5 is reachable.
""" """
def _checkERP5IsReachable(self, url): def _checkERP5IsReachable(self, url):
# What happens is that instanciation just create the services, but does not # What happens is that instantiation just create the services, but does not
# wait for ERP5 to be initialized. When this test run ERP5 instance is # wait for ERP5 to be initialized. When this test run ERP5 instance is
# instanciated, but zope is still busy creating the site and haproxy # instantiated, but zope is still busy creating the site and haproxy
# replies with 503 Service Unavailable when zope is not started yet, with # replies with 503 Service Unavailable when zope is not started yet, with
# 404 when erp5 site is not created, with 500 when mysql is not yet # 404 when erp5 site is not created, with 500 when mysql is not yet
# reachable, so we retry in a loop until we get a succesful response. # reachable, so we retry in a loop until we get a succesful response.
...@@ -85,7 +85,7 @@ class TestPublishedURLIsReachableMixin(object): ...@@ -85,7 +85,7 @@ class TestPublishedURLIsReachableMixin(object):
class TestDefaultParameters( class TestDefaultParameters(
ERP5InstanceTestCase, TestPublishedURLIsReachableMixin): ERP5InstanceTestCase, TestPublishedURLIsReachableMixin):
"""Test ERP5 can be instanciated with no parameters """Test ERP5 can be instantiated with no parameters
""" """
__partition_reference__ = 'defp' __partition_reference__ = 'defp'
...@@ -101,7 +101,7 @@ class TestMedusa(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin): ...@@ -101,7 +101,7 @@ class TestMedusa(ERP5InstanceTestCase, TestPublishedURLIsReachableMixin):
class TestApacheBalancerPorts(ERP5InstanceTestCase): class TestApacheBalancerPorts(ERP5InstanceTestCase):
"""Instanciate with two zope families, this should create for each family: """Instantiate with two zope families, this should create for each family:
- a balancer entry point with corresponding haproxy - a balancer entry point with corresponding haproxy
- a balancer entry point for test runner - a balancer entry point for test runner
""" """
...@@ -192,7 +192,7 @@ class TestApacheBalancerPorts(ERP5InstanceTestCase): ...@@ -192,7 +192,7 @@ class TestApacheBalancerPorts(ERP5InstanceTestCase):
class TestDisableTestRunner( class TestDisableTestRunner(
ERP5InstanceTestCase, TestPublishedURLIsReachableMixin): ERP5InstanceTestCase, TestPublishedURLIsReachableMixin):
"""Test ERP5 can be instanciated without test runner. """Test ERP5 can be instantiated without test runner.
""" """
__partition_reference__ = 'distr' __partition_reference__ = 'distr'
@classmethod @classmethod
......
...@@ -13,6 +13,7 @@ extra-eggs += ...@@ -13,6 +13,7 @@ extra-eggs +=
[template] [template]
extra = extra =
helloworld ${slapos.test.helloworld-setup:setup} helloworld ${slapos.test.helloworld-setup:setup}
jupyter ${slapos.test.jupyter-setup:setup}
monitor ${slapos.test.monitor-setup:setup} monitor ${slapos.test.monitor-setup:setup}
plantuml ${slapos.test.plantuml-setup:setup} plantuml ${slapos.test.plantuml-setup:setup}
powerdns ${slapos.test.powerdns-setup:setup} powerdns ${slapos.test.powerdns-setup:setup}
......
...@@ -47,6 +47,11 @@ setup = ${slapos-repository:location}/software/caddy-frontend/test/ ...@@ -47,6 +47,11 @@ setup = ${slapos-repository:location}/software/caddy-frontend/test/
egg = slapos.test.erp5 egg = slapos.test.erp5
setup = ${slapos-repository:location}/software/erp5/test/ setup = ${slapos-repository:location}/software/erp5/test/
[slapos.test.upgrade_erp5-setup]
<= setup-develop-egg
egg = slapos.test.upgrade_erp5
setup = ${slapos-repository:location}/software/erp5/upgrade_test/
[slapos.test.htmlvalidatorserver-setup] [slapos.test.htmlvalidatorserver-setup]
<= setup-develop-egg <= setup-develop-egg
egg = slapos.test.htmlvalidatorserver egg = slapos.test.htmlvalidatorserver
...@@ -185,6 +190,7 @@ extra-eggs = ...@@ -185,6 +190,7 @@ extra-eggs =
${slapos.test.backupserver-setup:egg} ${slapos.test.backupserver-setup:egg}
${slapos.test.caddy-frontend-setup:egg} ${slapos.test.caddy-frontend-setup:egg}
${slapos.test.erp5-setup:egg} ${slapos.test.erp5-setup:egg}
${slapos.test.upgrade_erp5-setup:egg}
${slapos.test.htmlvalidatorserver-setup:egg} ${slapos.test.htmlvalidatorserver-setup:egg}
${slapos.test.slapos-master-setup:egg} ${slapos.test.slapos-master-setup:egg}
${slapos.test.jstestnode-setup:egg} ${slapos.test.jstestnode-setup:egg}
...@@ -259,12 +265,12 @@ extra = ...@@ -259,12 +265,12 @@ extra =
backupserver ${slapos.test.backupserver-setup:setup} backupserver ${slapos.test.backupserver-setup:setup}
caddy-frontend ${slapos.test.caddy-frontend-setup:setup} caddy-frontend ${slapos.test.caddy-frontend-setup:setup}
erp5 ${slapos.test.erp5-setup:setup} erp5 ${slapos.test.erp5-setup:setup}
upgrade_erp5 ${slapos.test.upgrade_erp5-setup:setup}
htmlvalidatorserver ${slapos.test.htmlvalidatorserver-setup:setup} htmlvalidatorserver ${slapos.test.htmlvalidatorserver-setup:setup}
slapos-master ${slapos.test.slapos-master-setup:setup} slapos-master ${slapos.test.slapos-master-setup:setup}
re6stnet ${slapos.test.re6stnet-setup:setup} re6stnet ${slapos.test.re6stnet-setup:setup}
seleniumserver ${slapos.test.seleniumserver-setup:setup} seleniumserver ${slapos.test.seleniumserver-setup:setup}
jstestnode ${slapos.test.jstestnode-setup:setup} jstestnode ${slapos.test.jstestnode-setup:setup}
jupyter ${slapos.test.jupyter-setup:setup}
nextcloud ${slapos.test.nextcloud-setup:setup} nextcloud ${slapos.test.nextcloud-setup:setup}
turnserver ${slapos.test.turnserver-setup:setup} turnserver ${slapos.test.turnserver-setup:setup}
theia ${slapos.test.theia-setup:setup} theia ${slapos.test.theia-setup:setup}
...@@ -288,7 +294,6 @@ plantuml = 0.3.0 ...@@ -288,7 +294,6 @@ plantuml = 0.3.0
pysftp = 0.2.9 pysftp = 0.2.9
requests-toolbelt = 0.8.0 requests-toolbelt = 0.8.0
selenium = 3.141.0 selenium = 3.141.0
slapos.recipe.template = 4.4
# Patched eggs # Patched eggs
PyPDF2 = 1.26.0+SlapOSPatched001 PyPDF2 = 1.26.0+SlapOSPatched001
......
...@@ -203,14 +203,23 @@ output = ${buildout:directory}/template.cfg ...@@ -203,14 +203,23 @@ output = ${buildout:directory}/template.cfg
mode = 640 mode = 640
[versions] [versions]
# clear version pins of tested eggs for which we want to generate scripts # clear version pins of tested eggs, to make sure buildout always use the
# otherwise, the scripts will be generated for the pinned version. # git checkout version.
slapos.core = caucase =
erp5.util = erp5.util =
kedifa =
slapos.cookbook =
slapos.core =
slapos.libnetworkcache =
slapos.rebootstrap =
slapos.recipe.build =
slapos.recipe.cmmi =
slapos.recipe.template =
slapos.toolbox =
rubygemsrecipe =
# All depencies should be pinned. # All depencies should be pinned.
Pygments = 2.1.3 Pygments = 2.1.3
slapos.recipe.template = 4.4
zc.lockfile = 1.4 zc.lockfile = 1.4
bcrypt = 3.1.4 bcrypt = 3.1.4
dnspython = 1.15.0 dnspython = 1.15.0
......
...@@ -129,7 +129,7 @@ To create the frontend, you now have to wait the slaprunner to be processed. ...@@ -129,7 +129,7 @@ To create the frontend, you now have to wait the slaprunner to be processed.
You can define the type of your backend using "custom-frontend-backend-type". eg: zope You can define the type of your backend using "custom-frontend-backend-type". eg: zope
If you deploy a server, which uses basic auth, you also have to declare the parameter "custom-frontend-basic-auth" as true, or your slaprunner instance won't show as correctly instanciated. If you deploy a server, which uses basic auth, you also have to declare the parameter "custom-frontend-basic-auth" as true, or your slaprunner instance won't show as correctly instantiated.
Example : Example :
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
......
...@@ -18,7 +18,7 @@ md5sum = 8d6878ff1d2e75010c50a1a2b0c13b24 ...@@ -18,7 +18,7 @@ md5sum = 8d6878ff1d2e75010c50a1a2b0c13b24
[template-runner] [template-runner]
filename = instance-runner.cfg filename = instance-runner.cfg
md5sum = 2582723c31166244ff25cb3d8c839ffa md5sum = 9f367deb7597957e7108bee719b78bcc
[template-runner-import-script] [template-runner-import-script]
filename = template/runner-import.sh.jinja2 filename = template/runner-import.sh.jinja2
......
...@@ -262,7 +262,6 @@ template = inline: ...@@ -262,7 +262,6 @@ template = inline:
Port $${runner-sshd-port:port} Port $${runner-sshd-port:port}
ListenAddress $${slap-network-information:global-ipv6} ListenAddress $${slap-network-information:global-ipv6}
Protocol 2 Protocol 2
UsePrivilegeSeparation no
HostKey $${runner-sshd-ssh-host-rsa-key:output} HostKey $${runner-sshd-ssh-host-rsa-key:output}
HostKey $${runner-sshd-ssh-host-ecdsa-key:output} HostKey $${runner-sshd-ssh-host-ecdsa-key:output}
PasswordAuthentication no PasswordAuthentication no
......
...@@ -176,7 +176,6 @@ gitdb = 0.6.4 ...@@ -176,7 +176,6 @@ gitdb = 0.6.4
gunicorn = 19.10.0 gunicorn = 19.10.0
prettytable = 0.7.2 prettytable = 0.7.2
pycurl = 7.43.0 pycurl = 7.43.0
slapos.recipe.template = 4.4
collective.recipe.environment = 0.2.0 collective.recipe.environment = 0.2.0
smmap = 0.9.0 smmap = 0.9.0
lockfile = 0.12.2 lockfile = 0.12.2
...@@ -73,5 +73,4 @@ url = ${:_profile_base_location_}/config/${:filename} ...@@ -73,5 +73,4 @@ url = ${:_profile_base_location_}/config/${:filename}
filename = user_db.csv filename = user_db.csv
[versions] [versions]
slapos.recipe.template = 4.4
apache-libcloud = 2.4.0 apache-libcloud = 2.4.0
...@@ -59,7 +59,6 @@ eggs = collective.recipe.template ...@@ -59,7 +59,6 @@ eggs = collective.recipe.template
collective.recipe.template = 1.11 collective.recipe.template = 1.11
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.recipe.build = 0.28 slapos.recipe.build = 0.28
slapos.recipe.template = 4.4
# Replicate slapos stack, but without shacache to not have to compile the entire world for a simple test. # Replicate slapos stack, but without shacache to not have to compile the entire world for a simple test.
[buildout] [buildout]
......
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
[instance] [instance]
filename = instance.cfg.in filename = instance.cfg.in
md5sum = 1c60191f8724854f979a17d2624e65d8 md5sum = a3e4cb7d28daa7816f04359c8aa3445b
[yarn.lock] [yarn.lock]
filename = yarn.lock filename = yarn.lock
md5sum = 5a89742266a9f9d4115efa6d641fd5bb md5sum = e4b8d436916e48d354342894d6ffecb7
[python-language-server-requirements.txt] [python-language-server-requirements.txt]
filename = python-language-server-requirements.txt filename = python-language-server-requirements.txt
......
# This file is automatically generated from generate_download_plugins_cfg.py
# Do not edit directly.
[theia-download-plugins]
urls = vscode-bat https://open-vsx.org/api/vscode/bat/1.52.1/file/vscode.bat-1.52.1.vsix a01f2ac26bf94f37dec55ddcc1687229
vscode-clojure https://open-vsx.org/api/vscode/clojure/1.52.1/file/vscode.clojure-1.52.1.vsix 3ade86994f54f9d5e3636c22052c9cd2
vscode-coffeescript https://open-vsx.org/api/vscode/coffeescript/1.52.1/file/vscode.coffeescript-1.52.1.vsix 1493e64c31c5430f6ae98fde5035c430
vscode-configuration-editing https://open-vsx.org/api/vscode/configuration-editing/1.52.1/file/vscode.configuration-editing-1.52.1.vsix 27a31f7c1f1c16d6f3f5494a942803f8
vscode-cpp https://open-vsx.org/api/vscode/cpp/1.52.1/file/vscode.cpp-1.52.1.vsix a2aac35b43f5a63ac4ef94c818f7f2f0
vscode-csharp https://open-vsx.org/api/vscode/csharp/1.52.1/file/vscode.csharp-1.52.1.vsix 419835a40c743f9e6a298642d5c759f1
vscode-css https://open-vsx.org/api/vscode/css/1.52.1/file/vscode.css-1.52.1.vsix 4c71f2bcfb4235376cb8d9c91fdbd3b8
vscode-css-language-features https://open-vsx.org/api/vscode/css-language-features/1.52.1/file/vscode.css-language-features-1.52.1.vsix 14c7e5aaf53278fb8aab8043e840373e
vscode-debug-auto-launch https://open-vsx.org/api/vscode/debug-auto-launch/1.52.1/file/vscode.debug-auto-launch-1.52.1.vsix c7f66e6de1b3a1b770a6804f833f4a1e
vscode-docker https://open-vsx.org/api/vscode/docker/1.52.1/file/vscode.docker-1.52.1.vsix e3f9eda7a943bb2943acdf6aff532032
vscode-emmet https://open-vsx.org/api/vscode/emmet/1.52.1/file/vscode.emmet-1.52.1.vsix 7769b2f8b2ab1b95fe485be686cede40
vscode-fsharp https://open-vsx.org/api/vscode/fsharp/1.52.1/file/vscode.fsharp-1.52.1.vsix 57185c7f7470381751dc9fe119755a39
vscode-go https://open-vsx.org/api/vscode/go/1.52.1/file/vscode.go-1.52.1.vsix 54fe8f65196eb8eb8711231cec3c817c
vscode-groovy https://open-vsx.org/api/vscode/groovy/1.52.1/file/vscode.groovy-1.52.1.vsix 6f4d4eeef9f8b52fbb032e280bf451e5
vscode-grunt https://open-vsx.org/api/vscode/grunt/1.52.1/file/vscode.grunt-1.52.1.vsix fd6fdbcc2e1b5ebadab49e7595fe8002
vscode-gulp https://open-vsx.org/api/vscode/gulp/1.52.1/file/vscode.gulp-1.52.1.vsix 69518e0f85d123b3316423aa89a76e83
vscode-handlebars https://open-vsx.org/api/vscode/handlebars/1.52.1/file/vscode.handlebars-1.52.1.vsix 895e74ef84972eef3c99fdc19d365e9a
vscode-hlsl https://open-vsx.org/api/vscode/hlsl/1.52.1/file/vscode.hlsl-1.52.1.vsix ebfba5b2e17f20c3dc2009d4b04366f8
vscode-html https://open-vsx.org/api/vscode/html/1.52.1/file/vscode.html-1.52.1.vsix a22b3fbd69316a0083e86960474155a8
vscode-html-language-features https://open-vsx.org/api/vscode/html-language-features/1.52.1/file/vscode.html-language-features-1.52.1.vsix a83619f2924ec58713691e76f17c7fb6
vscode-ini https://open-vsx.org/api/vscode/ini/1.52.1/file/vscode.ini-1.52.1.vsix fbaef08e68b3a62285316d4fdc1ec053
vscode-jake https://open-vsx.org/api/vscode/jake/1.52.1/file/vscode.jake-1.52.1.vsix cf722e130ebb2b394c5755b1f1b83059
vscode-java https://open-vsx.org/api/vscode/java/1.52.1/file/vscode.java-1.52.1.vsix 597c25303c276a4e585430c717992b2d
vscode-javascript https://open-vsx.org/api/vscode/javascript/1.52.1/file/vscode.javascript-1.52.1.vsix 9e088a2862f7e9981a712f41b21e3e6d
ms-vscode-js-debug https://open-vsx.org/api/ms-vscode/js-debug/1.52.2/file/ms-vscode.js-debug-1.52.2.vsix f0f0c11c9c1855b6d3c87b230790c949
vscode-json https://open-vsx.org/api/vscode/json/1.52.1/file/vscode.json-1.52.1.vsix 42ded5b953546b95fb2cc1b6471fa3f6
vscode-json-language-features https://open-vsx.org/api/vscode/json-language-features/1.45.1/file/vscode.json-language-features-1.45.1.vsix b7aa9d96d67792dedf9c2558880f38c0
vscode-less https://open-vsx.org/api/vscode/less/1.52.1/file/vscode.less-1.52.1.vsix 19af098ed95926e0368e235b2c96d39d
vscode-log https://open-vsx.org/api/vscode/log/1.52.1/file/vscode.log-1.52.1.vsix 705da72c084b42f3033c60832272a84b
vscode-lua https://open-vsx.org/api/vscode/lua/1.52.1/file/vscode.lua-1.52.1.vsix 3eb0a5e77719ebbcc6681d96197dd1c4
vscode-make https://open-vsx.org/api/vscode/make/1.52.1/file/vscode.make-1.52.1.vsix abf5acf19bf7912bc5ef47364f3cb011
vscode-markdown https://open-vsx.org/api/vscode/markdown/1.52.1/file/vscode.markdown-1.52.1.vsix f3746e976590d9fb9fa9fc9cf5449e18
vscode-markdown-language-features https://open-vsx.org/api/vscode/markdown-language-features/1.39.1/file/vscode.markdown-language-features-1.39.1.vsix 530db5bd1fb926a008a85978e7dc22c0
vscode-merge-conflict https://open-vsx.org/api/vscode/merge-conflict/1.52.1/file/vscode.merge-conflict-1.52.1.vsix cdf4fccb4a9bf78bd6075128b9f33d86
vscode-npm https://open-vsx.org/api/vscode/npm/1.52.1/file/vscode.npm-1.52.1.vsix f0b8735948a07fbeb010d9919b6804b3
ms-vscode-node-debug https://open-vsx.org/api/ms-vscode/node-debug/1.44.8/file/ms-vscode.node-debug-1.44.8.vsix 367bac016859084e63acf792ed4a1aeb
ms-vscode-node-debug2 https://open-vsx.org/api/ms-vscode/node-debug2/1.42.5/file/ms-vscode.node-debug2-1.42.5.vsix 7882d7d90d18820be17aa5f3e12e71e1
vscode-objective-c https://open-vsx.org/api/vscode/objective-c/1.52.1/file/vscode.objective-c-1.52.1.vsix 02b1a5b99f2ef6e8617833e8bc77bb93
vscode-perl https://open-vsx.org/api/vscode/perl/1.52.1/file/vscode.perl-1.52.1.vsix 16101b0c282bd3a6df4a438b88642bc4
vscode-powershell https://open-vsx.org/api/vscode/powershell/1.52.1/file/vscode.powershell-1.52.1.vsix 037f61af26d7e7cd6dee82935c1e0e53
vscode-pug https://open-vsx.org/api/vscode/pug/1.52.1/file/vscode.pug-1.52.1.vsix 822611eea17432fa391ff9ee5850dbf9
vscode-python https://open-vsx.org/api/vscode/python/1.52.1/file/vscode.python-1.52.1.vsix 84afbfc12314ebd51e1172a42a1d8c16
vscode-r https://open-vsx.org/api/vscode/r/1.52.1/file/vscode.r-1.52.1.vsix 2d27ba0c50be592b3f2236762261cb2b
vscode-razor https://open-vsx.org/api/vscode/razor/1.52.1/file/vscode.razor-1.52.1.vsix 4a91958b7f7d8c40f44f2aaf7a24a23c
vscode-ruby https://open-vsx.org/api/vscode/ruby/1.52.1/file/vscode.ruby-1.52.1.vsix 9ca427d1762ee04c9db45e7263a1c517
vscode-rust https://open-vsx.org/api/vscode/rust/1.52.1/file/vscode.rust-1.52.1.vsix a3aabfa0c8b5243687cf585f57c09d69
vscode-scss https://open-vsx.org/api/vscode/scss/1.52.1/file/vscode.scss-1.52.1.vsix 5b5fb15380536fb32db04e8f73949269
vscode-shaderlab https://open-vsx.org/api/vscode/shaderlab/1.52.1/file/vscode.shaderlab-1.52.1.vsix 33a6a179c5ada2e2d41e5daa8dda3078
vscode-shellscript https://open-vsx.org/api/vscode/shellscript/1.52.1/file/vscode.shellscript-1.52.1.vsix 2833b96ac86906d09a64466542a9976a
vscode-sql https://open-vsx.org/api/vscode/sql/1.52.1/file/vscode.sql-1.52.1.vsix 80b86e17950d2b73366841d64a89d1fb
vscode-swift https://open-vsx.org/api/vscode/swift/1.52.1/file/vscode.swift-1.52.1.vsix 7d9af7d3808207c2f172947bc57c6138
vscode-theme-abyss https://open-vsx.org/api/vscode/theme-abyss/1.52.1/file/vscode.theme-abyss-1.52.1.vsix 932a6dff3f61a5fca776b1335c0fadcb
vscode-theme-defaults https://open-vsx.org/api/vscode/theme-defaults/1.52.1/file/vscode.theme-defaults-1.52.1.vsix ee0bd09cc2865306603ad7d3e4baf7c6
vscode-theme-kimbie-dark https://open-vsx.org/api/vscode/theme-kimbie-dark/1.52.1/file/vscode.theme-kimbie-dark-1.52.1.vsix cc521d79bfbac23469f5da7ca87fd569
vscode-theme-monokai https://open-vsx.org/api/vscode/theme-monokai/1.52.1/file/vscode.theme-monokai-1.52.1.vsix 63775bef9e965a56965a8577c148938a
vscode-theme-monokai-dimmed https://open-vsx.org/api/vscode/theme-monokai-dimmed/1.52.1/file/vscode.theme-monokai-dimmed-1.52.1.vsix d9d43239d1504c4e56c01f6c8f9934d0
vscode-theme-quietlight https://open-vsx.org/api/vscode/theme-quietlight/1.52.1/file/vscode.theme-quietlight-1.52.1.vsix 6022450d090d9141b5145365ac7aa658
vscode-theme-red https://open-vsx.org/api/vscode/theme-red/1.52.1/file/vscode.theme-red-1.52.1.vsix ccc68413dee562fa6066522771e11133
vscode-theme-solarized-dark https://open-vsx.org/api/vscode/theme-solarized-dark/1.52.1/file/vscode.theme-solarized-dark-1.52.1.vsix 3eb74a4c99a51540f8cb59f05ed0f75c
vscode-theme-tomorrow-night-blue https://open-vsx.org/api/vscode/theme-tomorrow-night-blue/1.52.1/file/vscode.theme-tomorrow-night-blue-1.52.1.vsix d6608555272ff8ac1824bab6ed1cde6d
vscode-typescript https://open-vsx.org/api/vscode/typescript/1.52.1/file/vscode.typescript-1.52.1.vsix 88747f9fe6f8e79c73bca94a0e71ee86
vscode-typescript-language-features https://open-vsx.org/api/vscode/typescript-language-features/1.52.1/file/vscode.typescript-language-features-1.52.1.vsix 766d7d9cb2028c87b9e0970bc0814428
vscode-vb https://open-vsx.org/api/vscode/vb/1.52.1/file/vscode.vb-1.52.1.vsix 3799c73c2b777db007c7cf12a1a5b341
vscode-vscode-theme-seti https://open-vsx.org/api/vscode/vscode-theme-seti/1.52.1/file/vscode.vscode-theme-seti-1.52.1.vsix 3c3c7e0eb21dc07e190576c5a885835f
vscode-xml https://open-vsx.org/api/vscode/xml/1.52.1/file/vscode.xml-1.52.1.vsix 52e3ad6e37eb41652d782227facb4675
vscode-yaml https://open-vsx.org/api/vscode/yaml/1.52.1/file/vscode.yaml-1.52.1.vsix f99e971bc121aea58ad354f72825ae77
EditorConfig-EditorConfig https://open-vsx.org/api/EditorConfig/EditorConfig/0.16.4/file/EditorConfig.EditorConfig-0.16.4.vsix 0f8e4278d7a3638b9f9df84a07a56021
dbaeumer-vscode-eslint https://open-vsx.org/api/dbaeumer/vscode-eslint/2.1.8/file/dbaeumer.vscode-eslint-2.1.8.vsix d3668785b2744386867631d79537552a
ms-vscode-references-view https://open-vsx.org/api/ms-vscode/references-view/0.0.75/file/ms-vscode.references-view-0.0.75.vsix fef3a672f5a332be40be1cc6f59bf50f
golang-Go https://open-vsx.org/api/golang/Go/0.16.2/file/golang.Go-0.16.2.vsix 2b0119ff72ac71658d043caed7bfb997
vscjava-vscode-java-debug https://open-vsx.org/api/vscjava/vscode-java-debug/0.29.0/file/vscjava.vscode-java-debug-0.29.0.vsix 1eb95110f84ff8dcabbe3c672066b86d
redhat-java https://open-vsx.org/api/redhat/java/0.61.0/file/redhat.java-0.61.0.vsix 72e548e2845e1ff655f28111558d6942
vscjava-vscode-java-test https://open-vsx.org/api/vscjava/vscode-java-test/0.26.0/file/vscjava.vscode-java-test-0.26.0.vsix fd63da5537a4bee1d3ceaae0fa6bf419
ms-python-python https://open-vsx.org/api/ms-python/python/2020.9.112786/file/ms-python.python-2020.9.112786.vsix c64b79fa822418e07b6d0f57b8838b44
perrinjerome-vscode-zc-buildout https://open-vsx.org/api/perrinjerome/vscode-zc-buildout/0.4.0/file/perrinjerome.vscode-zc-buildout-0.4.0.vsix 028d2f77bd101d6388ded1839a60feaa
jebbs-plantuml https://open-vsx.org/api/jebbs/plantuml/2.13.12/file/jebbs.plantuml-2.13.12.vsix abb0e20fa1f93537ac6966085e678c31
rafaelmaiolla-diff https://open-vsx.org/api/rafaelmaiolla/diff/0.0.1/file/rafaelmaiolla.diff-0.0.1.vsix 1d8f868bc19b7d703c1be2bf99c4c7f9
perrinjerome-git-commit-syntax https://open-vsx.org/api/perrinjerome/git-commit-syntax/0.0.1/file/perrinjerome.git-commit-syntax-0.0.1.vsix 46625f2f05e244911c2cb9cc5032c0ef
perrinjerome-git-rebase-syntax https://open-vsx.org/api/perrinjerome/git-rebase-syntax/0.0.1/file/perrinjerome.git-rebase-syntax-0.0.1.vsix cf899a240b78f6766b85fa14d543a6ea
import configparser
import requests
import hashlib
urls = []
for plugin_and_version in '''\
vscode/bat/latest
vscode/clojure/latest
vscode/coffeescript/latest
vscode/configuration-editing/latest
vscode/cpp/latest
vscode/csharp/latest
vscode/css/latest
vscode/css-language-features/latest
vscode/debug-auto-launch/latest
vscode/docker/latest
vscode/emmet/latest
vscode/fsharp/latest
vscode/go/latest
vscode/groovy/latest
vscode/grunt/latest
vscode/gulp/latest
vscode/handlebars/latest
vscode/hlsl/latest
vscode/html/latest
vscode/html-language-features/latest
vscode/ini/latest
vscode/jake/latest
vscode/java/latest
vscode/javascript/latest
ms-vscode/js-debug/latest
vscode/json/latest
# latest json-language-features does offer completions with .theia/settings.json
vscode/json-language-features/1.45.1
vscode/less/latest
vscode/log/latest
vscode/lua/latest
vscode/make/latest
vscode/markdown/latest
# https://github.com/eclipse-theia/theia/issues/7780
vscode/markdown-language-features/1.39.1
vscode/merge-conflict/latest
vscode/npm/latest
ms-vscode/node-debug/latest
ms-vscode/node-debug2/latest
vscode/objective-c/latest
vscode/perl/latest
vscode/powershell/latest
vscode/pug/latest
vscode/python/latest
vscode/r/latest
vscode/razor/latest
vscode/ruby/latest
vscode/rust/latest
vscode/scss/latest
vscode/shaderlab/latest
vscode/shellscript/latest
vscode/sql/latest
vscode/swift/latest
vscode/theme-abyss/latest
vscode/theme-defaults/latest
vscode/theme-kimbie-dark/latest
vscode/theme-monokai/latest
vscode/theme-monokai-dimmed/latest
vscode/theme-quietlight/latest
vscode/theme-red/latest
vscode/theme-solarized-dark/latest
vscode/theme-tomorrow-night-blue/latest
vscode/typescript/latest
vscode/typescript-language-features/latest
vscode/vb/latest
vscode/vscode-theme-seti/latest
vscode/xml/latest
vscode/yaml/latest
EditorConfig/EditorConfig/latest
dbaeumer/vscode-eslint/latest
ms-vscode/references-view/latest
golang/Go/0.16.2
vscjava/vscode-java-debug/0.29.0
redhat/java/0.61.0
vscjava/vscode-java-test/0.26.0
ms-python/python/2020.9.112786
perrinjerome/vscode-zc-buildout/latest
jebbs/plantuml/2.13.12
rafaelmaiolla/diff/latest
perrinjerome/git-commit-syntax/latest
perrinjerome/git-rebase-syntax/latest
'''.splitlines():
plugin_and_version = plugin_and_version.strip()
if not plugin_and_version or plugin_and_version.startswith('#'):
continue
publisher, extension_name, version = plugin_and_version.split('/')
api_url = f'https://open-vsx.org/api/{publisher}/{extension_name}/{version}'
download_url = requests.get(api_url).json()['files']['download']
md5sum = hashlib.md5(requests.get(download_url).content).hexdigest()
urls.append(f'{publisher}-{extension_name} {download_url} {md5sum}')
cfg = configparser.ConfigParser()
cfg.add_section('theia-download-plugins')
cfg.set('theia-download-plugins', 'urls', '\n'.join(urls))
with open('download-plugins.cfg', 'w') as f:
f.write(f"""\
# This file is automatically generated from {__file__}
# Do not edit directly.
""")
cfg.write(f)
...@@ -5,6 +5,9 @@ parts = ...@@ -5,6 +5,9 @@ parts =
frontend-reload frontend-reload
tasks.json tasks.json
publish-connection-parameter publish-connection-parameter
slapos-repository
runner-link
settings.json
extends = ${monitor-template:rendered} extends = ${monitor-template:rendered}
...@@ -392,6 +395,36 @@ url = $${slap-connection:server-url} ...@@ -392,6 +395,36 @@ url = $${slap-connection:server-url}
key = $${slap-connection:key-file} key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file} cert = $${slap-connection:cert-file}
[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}
[directory] [directory]
recipe = slapos.cookbook:mkdirectory recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc etc = $${buildout:directory}/etc
......
...@@ -16,6 +16,7 @@ extends = ...@@ -16,6 +16,7 @@ extends =
../../stack/slapos.cfg ../../stack/slapos.cfg
../../stack/monitor/buildout.cfg ../../stack/monitor/buildout.cfg
../../component/defaults.cfg ../../component/defaults.cfg
./download-plugins.cfg
./buildout.hash.cfg ./buildout.hash.cfg
parts = parts =
...@@ -168,17 +169,26 @@ command = ${bash:location}/bin/bash -c " ...@@ -168,17 +169,26 @@ command = ${bash:location}/bin/bash -c "
export TMPDIR=${:location}/tmp PATH=${nodejs:location}/bin:$PATH && export TMPDIR=${:location}/tmp PATH=${nodejs:location}/bin:$PATH &&
mkdir -p ${:location} && \ mkdir -p ${:location} && \
mkdir -p \$TMPDIR && \ mkdir -p \$TMPDIR && \
mkdir -p ${:THEIA_DEFAULT_PLUGINS} && \
cd ${:location} && \ cd ${:location} && \
cp ${package.json:rendered} . && cp ${package.json:rendered} . &&
cp ${yarn.lock:output} . && cp ${yarn.lock:output} . &&
${yarn:location}/bin/yarn && \ ${yarn:location}/bin/yarn && \
${yarn:location}/bin/yarn theia build && \ ${yarn:location}/bin/yarn theia build"
${yarn:location}/bin/yarn theia download:plugins"
location = ${buildout:parts-directory}/${:_buildout_section_name_} location = ${buildout:parts-directory}/${:_buildout_section_name_}
stop-on-error = true stop-on-error = true
uses = ${yarn.lock:recipe} uses = ${yarn.lock:recipe}
THEIA_DEFAULT_PLUGINS = ${:location}/plugins/
[theia-plugins]
recipe = slapos.recipe.build
urls = ${theia-download-plugins:urls}
install =
import os
for line in options['urls'].splitlines():
extension_name, url, md5sum = line.split()
extract_dir = self.extract(self.download(url, md5sum))
destination_dir = os.path.join(options['location'], extension_name)
self.copyTree(guessworkdir(extract_dir), destination_dir)
os.chmod(destination_dir, 0o750)
[yarn.lock] [yarn.lock]
<= template-base <= template-base
...@@ -194,8 +204,6 @@ THEIA_DEFAULT_PLUGINS = ${:location}/plugins/ ...@@ -194,8 +204,6 @@ THEIA_DEFAULT_PLUGINS = ${:location}/plugins/
[package.json] [package.json]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
# this comes from https://github.com/theia-ide/theia-apps/blob/a54aaa676e3db07d22ab75dde9f3447576135b4d/theia-full-docker/latest.package.json
# but with a more recent version of vscode-java-redhat, where https://github.com/redhat-developer/vscode-java/issues/1301 was fixed
template = template =
inline:{ inline:{
"private": true, "private": true,
...@@ -205,6 +213,9 @@ template = ...@@ -205,6 +213,9 @@ template =
"applicationName": "Theia SlapOS", "applicationName": "Theia SlapOS",
"preferences": { "preferences": {
"application.confirmExit": "always", "application.confirmExit": "always",
"files.associations": {
"*.cfg": "zc-buildout"
},
"files.enableTrash": false, "files.enableTrash": false,
"files.exclude": { "files.exclude": {
"**.pyc": true, "**.pyc": true,
...@@ -275,85 +286,6 @@ template = ...@@ -275,85 +286,6 @@ template =
}, },
"devDependencies": { "devDependencies": {
"@theia/cli": "latest" "@theia/cli": "latest"
},
"theiaPluginsDir": "plugins",
"theiaPlugins": {
"vscode-builtin-bat": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/bat-1.39.1-prel.vsix",
"vscode-builtin-clojure": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/clojure-1.39.1-prel.vsix",
"vscode-builtin-coffeescript": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/coffeescript-1.39.1-prel.vsix",
"vscode-builtin-configuration-editing": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/configuration-editing-1.39.1-prel.vsix",
"vscode-builtin-cpp": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/cpp-1.39.1-prel.vsix",
"vscode-builtin-csharp": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/csharp-1.39.1-prel.vsix",
"vscode-builtin-css": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/css-1.39.1-prel.vsix",
"vscode-builtin-debug-auto-launch": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/debug-auto-launch-1.39.1-prel.vsix",
"vscode-builtin-docker": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/docker-1.39.1-prel.vsix",
"vscode-builtin-emmet": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/emmet-1.39.1-prel.vsix",
"vscode-builtin-fsharp": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/fsharp-1.39.1-prel.vsix",
"vscode-builtin-go": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/go-1.39.1-prel.vsix",
"vscode-builtin-groovy": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/groovy-1.39.1-prel.vsix",
"vscode-builtin-grunt": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/grunt-1.39.1-prel.vsix",
"vscode-builtin-gulp": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/gulp-1.39.1-prel.vsix",
"vscode-builtin-handlebars": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/handlebars-1.39.1-prel.vsix",
"vscode-builtin-hlsl": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/hlsl-1.39.1-prel.vsix",
"vscode-builtin-html": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/html-1.39.1-prel.vsix",
"vscode-builtin-ini": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/ini-1.39.1-prel.vsix",
"vscode-builtin-jake": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/jake-1.39.1-prel.vsix",
"vscode-builtin-java": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/java-1.39.1-prel.vsix",
"vscode-builtin-javascript": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/javascript-1.39.1-prel.vsix",
"vscode-builtin-json": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/json-1.39.1-prel.vsix",
"vscode-builtin-json-language-features": "https://open-vsx.org/api/vscode/json-language-features/1.46.1/file/vscode.json-language-features-1.46.1.vsix",
"vscode-builtin-less": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/less-1.39.1-prel.vsix",
"vscode-builtin-log": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/log-1.39.1-prel.vsix",
"vscode-builtin-lua": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/lua-1.39.1-prel.vsix",
"vscode-builtin-make": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/make-1.39.1-prel.vsix",
"vscode-builtin-markdown": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/markdown-1.39.1-prel.vsix",
"vscode-builtin-merge-conflicts": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/merge-conflict-1.39.1-prel.vsix",
"vscode-builtin-npm": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/npm-1.39.1-prel.vsix",
"vscode-builtin-node-debug": "https://github.com/theia-ide/vscode-node-debug/releases/download/v1.35.3/node-debug-1.35.3.vsix",
"vscode-builtin-node-debug2": "https://github.com/theia-ide/vscode-node-debug2/releases/download/v1.33.0/node-debug2-1.33.0.vsix",
"vscode-builtin-objective-c": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/objective-c-1.39.1-prel.vsix",
"vscode-builtin-perl": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/perl-1.39.1-prel.vsix",
"vscode-builtin-powershell": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/powershell-1.39.1-prel.vsix",
"vscode-builtin-pug": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/pug-1.39.1-prel.vsix",
"vscode-builtin-python": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/python-1.39.1-prel.vsix",
"vscode-builtin-r": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/r-1.39.1-prel.vsix",
"vscode-builtin-razor": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/razor-1.39.1-prel.vsix",
"vscode-builtin-ruby": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/ruby-1.39.1-prel.vsix",
"vscode-builtin-rust": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/rust-1.39.1-prel.vsix",
"vscode-builtin-scss": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/scss-1.39.1-prel.vsix",
"vscode-builtin-shaderlab": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/shaderlab-1.39.1-prel.vsix",
"vscode-builtin-shellscript": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/shellscript-1.39.1-prel.vsix",
"vscode-builtin-sql": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/sql-1.39.1-prel.vsix",
"vscode-builtin-swift": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/swift-1.39.1-prel.vsix",
"vscode-builtin-theme-abyss": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-abyss-1.39.1-prel.vsix",
"vscode-builtin-theme-defaults": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-defaults-1.39.1-prel.vsix",
"vscode-builtin-theme-kimbie-dark": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-kimbie-dark-1.39.1-prel.vsix",
"vscode-builtin-theme-monokai": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-monokai-1.39.1-prel.vsix",
"vscode-builtin-theme-dimmed": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-monokai-dimmed-1.39.1-prel.vsix",
"vscode-builtin-theme-quietlight": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-quietlight-1.39.1-prel.vsix",
"vscode-builtin-theme-red": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-red-1.39.1-prel.vsix",
"vscode-builtin-theme-solarized-dark": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-solarized-dark-1.39.1-prel.vsix",
"vscode-builtin-theme-tomorrow-night-blue": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/theme-tomorrow-night-blue-1.39.1-prel.vsix",
"vscode-builtin-typescript": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/typescript-1.39.1-prel.vsix",
"vscode-builtin-typescript-language-features": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/typescript-language-features-1.39.1-prel.vsix",
"vscode-builtin-vb": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/vb-1.39.1-prel.vsix",
"vscode-builtin-icon-theme-seti": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/vscode-theme-seti-1.39.1-prel.vsix",
"vscode-builtin-xml": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/xml-1.39.1-prel.vsix",
"vscode-builtin-yaml": "https://github.com/theia-ide/vscode-builtin-extensions/releases/download/v1.39.1-prel/yaml-1.39.1-prel.vsix",
"vscode-editorconfig": "https://github.com/theia-ide/editorconfig-vscode/releases/download/v0.14.4/EditorConfig-0.14.4.vsix",
"vscode-eslint": "https://github.com/theia-ide/vscode-eslint/releases/download/release%2F2.0.15/vscode-eslint-2.0.15.vsix",
"vscode-go": "https://github.com/microsoft/vscode-go/releases/download/0.12.0/Go-0.12.0.vsix",
"vscode-java-debug": "https://github.com/microsoft/vscode-java-debug/releases/download/0.24.0/vscjava.vscode-java-debug-0.24.0.vsix",
"vscode-java-dependency-viewer": "https://github.com/microsoft/vscode-java-dependency/releases/download/0.6.0/vscode-java-dependency-0.6.0.vsix",
"vscode-java-redhat": "https://github.com/redhat-developer/vscode-java/releases/download/v0.61.0/redhat.java-0.61.0.vsix",
"vscode-java-test": "https://github.com/microsoft/vscode-java-test/releases/download/0.22.0/vscjava.vscode-java-test-0.22.0.vsix",
"vscode-python": "https://github.com/microsoft/vscode-python/releases/download/2020.1.58038/ms-python-release.vsix",
"vscode-ruby": "https://github.com/rubyide/vscode-ruby/releases/download/v0.25.0/ruby-0.25.0.vsix",
"vscode-zc-buildout": "https://github.com/perrinjerome/vscode-zc-buildout/releases/download/v0.4.0/vscode-zc-buildout-0.4.0.vsix",
"plantuml": "https://open-vsx.org/api/jebbs/plantuml/2.13.12/file/jebbs.plantuml-2.13.12.vsix",
"diff": "https://open-vsx.org/api/rafaelmaiolla/diff/0.0.1/file/rafaelmaiolla.diff-0.0.1.vsix",
"git-commit-syntax": "https://github.com/perrinjerome/git-commit-syntax/releases/download/v0.0.1/git-commit-syntax-0.0.1.vsix",
"git-rebase-syntax": "https://github.com/perrinjerome/git-rebase-syntax/releases/download/v0.0.1/git-rebase-syntax-0.0.1.vsix"
} }
} }
rendered = ${buildout:directory}/${:_buildout_section_name_} rendered = ${buildout:directory}/${:_buildout_section_name_}
...@@ -380,7 +312,7 @@ template = ...@@ -380,7 +312,7 @@ template =
#!/bin/bash #!/bin/bash
. ${gowork:env.sh} . ${gowork:env.sh}
export PATH=${python-language-server:location}/bin/:${java-jdk:location}/bin/:${cli-utilities:PATH}:$HOME/.cargo/bin:$PATH export PATH=${python-language-server:location}/bin/:${java-jdk:location}/bin/:${cli-utilities:PATH}:$HOME/.cargo/bin:$PATH
export THEIA_DEFAULT_PLUGINS="local-dir:${theia:THEIA_DEFAULT_PLUGINS}" export THEIA_DEFAULT_PLUGINS="local-dir:${theia-plugins:location}"
# reset PS1 from gowork # reset PS1 from gowork
export PS1='$ ' export PS1='$ '
cd ${theia:location} cd ${theia:location}
...@@ -390,6 +322,3 @@ template = ...@@ -390,6 +322,3 @@ template =
[instance] [instance]
<= template-base <= template-base
output = ${buildout:directory}/instance.cfg output = ${buildout:directory}/instance.cfg
[versions]
slapos.recipe.template = 4.4
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4":
version "7.10.4" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
dependencies: dependencies:
"@babel/highlight" "^7.10.4" "@babel/highlight" "^7.10.4"
...@@ -15,42 +15,41 @@ ...@@ -15,42 +15,41 @@
integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==
"@babel/core@^7.10.0": "@babel/core@^7.10.0":
version "7.12.9" version "7.12.10"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd"
integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==
dependencies: dependencies:
"@babel/code-frame" "^7.10.4" "@babel/code-frame" "^7.10.4"
"@babel/generator" "^7.12.5" "@babel/generator" "^7.12.10"
"@babel/helper-module-transforms" "^7.12.1" "@babel/helper-module-transforms" "^7.12.1"
"@babel/helpers" "^7.12.5" "@babel/helpers" "^7.12.5"
"@babel/parser" "^7.12.7" "@babel/parser" "^7.12.10"
"@babel/template" "^7.12.7" "@babel/template" "^7.12.7"
"@babel/traverse" "^7.12.9" "@babel/traverse" "^7.12.10"
"@babel/types" "^7.12.7" "@babel/types" "^7.12.10"
convert-source-map "^1.7.0" convert-source-map "^1.7.0"
debug "^4.1.0" debug "^4.1.0"
gensync "^1.0.0-beta.1" gensync "^1.0.0-beta.1"
json5 "^2.1.2" json5 "^2.1.2"
lodash "^4.17.19" lodash "^4.17.19"
resolve "^1.3.2"
semver "^5.4.1" semver "^5.4.1"
source-map "^0.5.0" source-map "^0.5.0"
"@babel/generator@^7.12.5": "@babel/generator@^7.12.10":
version "7.12.5" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af"
integrity sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A== integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==
dependencies: dependencies:
"@babel/types" "^7.12.5" "@babel/types" "^7.12.11"
jsesc "^2.5.1" jsesc "^2.5.1"
source-map "^0.5.0" source-map "^0.5.0"
"@babel/helper-annotate-as-pure@^7.10.4": "@babel/helper-annotate-as-pure@^7.10.4":
version "7.10.4" version "7.12.10"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz#54ab9b000e60a93644ce17b3f37d313aaf1d115d"
integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== integrity sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==
dependencies: dependencies:
"@babel/types" "^7.10.4" "@babel/types" "^7.12.10"
"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": "@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4":
version "7.10.4" version "7.10.4"
...@@ -106,20 +105,20 @@ ...@@ -106,20 +105,20 @@
"@babel/types" "^7.12.1" "@babel/types" "^7.12.1"
"@babel/helper-function-name@^7.10.4": "@babel/helper-function-name@^7.10.4":
version "7.10.4" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42"
integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==
dependencies: dependencies:
"@babel/helper-get-function-arity" "^7.10.4" "@babel/helper-get-function-arity" "^7.12.10"
"@babel/template" "^7.10.4" "@babel/template" "^7.12.7"
"@babel/types" "^7.10.4" "@babel/types" "^7.12.11"
"@babel/helper-get-function-arity@^7.10.4": "@babel/helper-get-function-arity@^7.12.10":
version "7.10.4" version "7.12.10"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf"
integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==
dependencies: dependencies:
"@babel/types" "^7.10.4" "@babel/types" "^7.12.10"
"@babel/helper-hoist-variables@^7.10.4": "@babel/helper-hoist-variables@^7.10.4":
version "7.10.4" version "7.10.4"
...@@ -128,7 +127,7 @@ ...@@ -128,7 +127,7 @@
dependencies: dependencies:
"@babel/types" "^7.10.4" "@babel/types" "^7.10.4"
"@babel/helper-member-expression-to-functions@^7.12.1": "@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.12.7":
version "7.12.7" version "7.12.7"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855"
integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==
...@@ -157,12 +156,12 @@ ...@@ -157,12 +156,12 @@
"@babel/types" "^7.12.1" "@babel/types" "^7.12.1"
lodash "^4.17.19" lodash "^4.17.19"
"@babel/helper-optimise-call-expression@^7.10.4": "@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.12.10":
version "7.12.7" version "7.12.10"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.7.tgz#7f94ae5e08721a49467346aa04fd22f750033b9c" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d"
integrity sha512-I5xc9oSJ2h59OwyUqjv95HRyzxj53DAubUERgQMrpcCEYQyToeHA+NEcUEsVWB4j53RDeskeBJ0SgRAYHDBckw== integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==
dependencies: dependencies:
"@babel/types" "^7.12.7" "@babel/types" "^7.12.10"
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
version "7.10.4" version "7.10.4"
...@@ -179,14 +178,14 @@ ...@@ -179,14 +178,14 @@
"@babel/types" "^7.12.1" "@babel/types" "^7.12.1"
"@babel/helper-replace-supers@^7.12.1": "@babel/helper-replace-supers@^7.12.1":
version "7.12.5" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz#f009a17543bbbbce16b06206ae73b63d3fca68d9" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d"
integrity sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA== integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==
dependencies: dependencies:
"@babel/helper-member-expression-to-functions" "^7.12.1" "@babel/helper-member-expression-to-functions" "^7.12.7"
"@babel/helper-optimise-call-expression" "^7.10.4" "@babel/helper-optimise-call-expression" "^7.12.10"
"@babel/traverse" "^7.12.5" "@babel/traverse" "^7.12.10"
"@babel/types" "^7.12.5" "@babel/types" "^7.12.11"
"@babel/helper-simple-access@^7.12.1": "@babel/helper-simple-access@^7.12.1":
version "7.12.1" version "7.12.1"
...@@ -203,21 +202,21 @@ ...@@ -203,21 +202,21 @@
"@babel/types" "^7.12.1" "@babel/types" "^7.12.1"
"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": "@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0":
version "7.11.0" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a"
integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==
dependencies: dependencies:
"@babel/types" "^7.11.0" "@babel/types" "^7.12.11"
"@babel/helper-validator-identifier@^7.10.4": "@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11":
version "7.10.4" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
"@babel/helper-validator-option@^7.12.1": "@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11":
version "7.12.1" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz#175567380c3e77d60ff98a54bb015fe78f2178d9" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f"
integrity sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A== integrity sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==
"@babel/helper-wrap-function@^7.10.4": "@babel/helper-wrap-function@^7.10.4":
version "7.12.3" version "7.12.3"
...@@ -247,10 +246,10 @@ ...@@ -247,10 +246,10 @@
chalk "^2.0.0" chalk "^2.0.0"
js-tokens "^4.0.0" js-tokens "^4.0.0"
"@babel/parser@^7.12.7": "@babel/parser@^7.12.10", "@babel/parser@^7.12.7":
version "7.12.7" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.7.tgz#fee7b39fe809d0e73e5b25eecaf5780ef3d73056" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79"
integrity sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg== integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==
"@babel/plugin-proposal-async-generator-functions@^7.12.1": "@babel/plugin-proposal-async-generator-functions@^7.12.1":
version "7.12.1" version "7.12.1"
...@@ -466,10 +465,10 @@ ...@@ -466,10 +465,10 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-transform-block-scoping@^7.12.1": "@babel/plugin-transform-block-scoping@^7.12.11":
version "7.12.1" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz#f0ee727874b42a208a48a586b84c3d222c2bbef1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.11.tgz#83ae92a104dbb93a7d6c6dd1844f351083c46b4f"
integrity sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w== integrity sha512-atR1Rxc3hM+VPg/NvNvfYw0npQEAcHuJ+MGZnFn6h3bo+1U3BWXMdFMlvVRApBTWKQMX7SOwRJZA5FBF/JQbvA==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4"
...@@ -642,13 +641,12 @@ ...@@ -642,13 +641,12 @@
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-transform-runtime@^7.10.0": "@babel/plugin-transform-runtime@^7.10.0":
version "7.12.1" version "7.12.10"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz#04b792057eb460389ff6a4198e377614ea1e7ba5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz#af0fded4e846c4b37078e8e5d06deac6cd848562"
integrity sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg== integrity sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA==
dependencies: dependencies:
"@babel/helper-module-imports" "^7.12.1" "@babel/helper-module-imports" "^7.12.5"
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4"
resolve "^1.8.1"
semver "^5.5.1" semver "^5.5.1"
"@babel/plugin-transform-shorthand-properties@^7.12.1": "@babel/plugin-transform-shorthand-properties@^7.12.1":
...@@ -680,10 +678,10 @@ ...@@ -680,10 +678,10 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-transform-typeof-symbol@^7.12.1": "@babel/plugin-transform-typeof-symbol@^7.12.10":
version "7.12.1" version "7.12.10"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.1.tgz#9ca6be343d42512fbc2e68236a82ae64bc7af78a" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz#de01c4c8f96580bd00f183072b0d0ecdcf0dec4b"
integrity sha512-EPGgpGy+O5Kg5pJFNDKuxt9RdmTgj5sgrus2XVeMp/ZIbOESadgILUbm50SNpghOh3/6yrbsH+NB5+WJTmsA7Q== integrity sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4"
...@@ -703,15 +701,15 @@ ...@@ -703,15 +701,15 @@
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4"
"@babel/preset-env@^7.10.0": "@babel/preset-env@^7.10.0":
version "7.12.7" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.7.tgz#54ea21dbe92caf6f10cb1a0a576adc4ebf094b55" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9"
integrity sha512-OnNdfAr1FUQg7ksb7bmbKoby4qFOHw6DKWWUNB9KqnnCldxhxJlP+21dpyaWFmf2h0rTbOkXJtAGevY3XW1eew== integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==
dependencies: dependencies:
"@babel/compat-data" "^7.12.7" "@babel/compat-data" "^7.12.7"
"@babel/helper-compilation-targets" "^7.12.5" "@babel/helper-compilation-targets" "^7.12.5"
"@babel/helper-module-imports" "^7.12.5" "@babel/helper-module-imports" "^7.12.5"
"@babel/helper-plugin-utils" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4"
"@babel/helper-validator-option" "^7.12.1" "@babel/helper-validator-option" "^7.12.11"
"@babel/plugin-proposal-async-generator-functions" "^7.12.1" "@babel/plugin-proposal-async-generator-functions" "^7.12.1"
"@babel/plugin-proposal-class-properties" "^7.12.1" "@babel/plugin-proposal-class-properties" "^7.12.1"
"@babel/plugin-proposal-dynamic-import" "^7.12.1" "@babel/plugin-proposal-dynamic-import" "^7.12.1"
...@@ -740,7 +738,7 @@ ...@@ -740,7 +738,7 @@
"@babel/plugin-transform-arrow-functions" "^7.12.1" "@babel/plugin-transform-arrow-functions" "^7.12.1"
"@babel/plugin-transform-async-to-generator" "^7.12.1" "@babel/plugin-transform-async-to-generator" "^7.12.1"
"@babel/plugin-transform-block-scoped-functions" "^7.12.1" "@babel/plugin-transform-block-scoped-functions" "^7.12.1"
"@babel/plugin-transform-block-scoping" "^7.12.1" "@babel/plugin-transform-block-scoping" "^7.12.11"
"@babel/plugin-transform-classes" "^7.12.1" "@babel/plugin-transform-classes" "^7.12.1"
"@babel/plugin-transform-computed-properties" "^7.12.1" "@babel/plugin-transform-computed-properties" "^7.12.1"
"@babel/plugin-transform-destructuring" "^7.12.1" "@babel/plugin-transform-destructuring" "^7.12.1"
...@@ -766,12 +764,12 @@ ...@@ -766,12 +764,12 @@
"@babel/plugin-transform-spread" "^7.12.1" "@babel/plugin-transform-spread" "^7.12.1"
"@babel/plugin-transform-sticky-regex" "^7.12.7" "@babel/plugin-transform-sticky-regex" "^7.12.7"
"@babel/plugin-transform-template-literals" "^7.12.1" "@babel/plugin-transform-template-literals" "^7.12.1"
"@babel/plugin-transform-typeof-symbol" "^7.12.1" "@babel/plugin-transform-typeof-symbol" "^7.12.10"
"@babel/plugin-transform-unicode-escapes" "^7.12.1" "@babel/plugin-transform-unicode-escapes" "^7.12.1"
"@babel/plugin-transform-unicode-regex" "^7.12.1" "@babel/plugin-transform-unicode-regex" "^7.12.1"
"@babel/preset-modules" "^0.1.3" "@babel/preset-modules" "^0.1.3"
"@babel/types" "^7.12.7" "@babel/types" "^7.12.11"
core-js-compat "^3.7.0" core-js-compat "^3.8.0"
semver "^5.5.0" semver "^5.5.0"
"@babel/preset-modules@^0.1.3": "@babel/preset-modules@^0.1.3":
...@@ -801,27 +799,27 @@ ...@@ -801,27 +799,27 @@
"@babel/parser" "^7.12.7" "@babel/parser" "^7.12.7"
"@babel/types" "^7.12.7" "@babel/types" "^7.12.7"
"@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.5", "@babel/traverse@^7.12.9": "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5":
version "7.12.9" version "7.12.10"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.9.tgz#fad26c972eabbc11350e0b695978de6cc8e8596f" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.10.tgz#2d1f4041e8bf42ea099e5b2dc48d6a594c00017a"
integrity sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw== integrity sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==
dependencies: dependencies:
"@babel/code-frame" "^7.10.4" "@babel/code-frame" "^7.10.4"
"@babel/generator" "^7.12.5" "@babel/generator" "^7.12.10"
"@babel/helper-function-name" "^7.10.4" "@babel/helper-function-name" "^7.10.4"
"@babel/helper-split-export-declaration" "^7.11.0" "@babel/helper-split-export-declaration" "^7.11.0"
"@babel/parser" "^7.12.7" "@babel/parser" "^7.12.10"
"@babel/types" "^7.12.7" "@babel/types" "^7.12.10"
debug "^4.1.0" debug "^4.1.0"
globals "^11.1.0" globals "^11.1.0"
lodash "^4.17.19" lodash "^4.17.19"
"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4": "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4":
version "7.12.7" version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.7.tgz#6039ff1e242640a29452c9ae572162ec9a8f5d13" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.11.tgz#a86e4d71e30a9b6ee102590446c98662589283ce"
integrity sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ== integrity sha512-ukA9SQtKThINm++CX1CwmliMrE54J6nIYB5XTwL5f/CLFW9owfls+YSU8tVW15RQ2w+a3fSbPjC6HdQNtWZkiA==
dependencies: dependencies:
"@babel/helper-validator-identifier" "^7.10.4" "@babel/helper-validator-identifier" "^7.12.11"
lodash "^4.17.19" lodash "^4.17.19"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
...@@ -973,16 +971,16 @@ ...@@ -973,16 +971,16 @@
resolved "https://registry.yarnpkg.com/@stroncium/procfs/-/procfs-1.2.1.tgz#6b9be6fd20fb0a4c20e99a8695e083c699bb2b45" resolved "https://registry.yarnpkg.com/@stroncium/procfs/-/procfs-1.2.1.tgz#6b9be6fd20fb0a4c20e99a8695e083c699bb2b45"
integrity sha512-X1Iui3FUNZP18EUvysTHxt+Avu2nlVzyf90YM8OYgP6SGzTzzX/0JgObfO1AQQDzuZtNNz29bVh8h5R97JrjxA== integrity sha512-X1Iui3FUNZP18EUvysTHxt+Avu2nlVzyf90YM8OYgP6SGzTzzX/0JgObfO1AQQDzuZtNNz29bVh8h5R97JrjxA==
"@theia/application-manager@^1.8.0": "@theia/application-manager@^1.9.0":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/application-manager/-/application-manager-1.8.0.tgz#4870935a0f95f2f6a96227063bdbe67dcd18d31b" resolved "https://registry.yarnpkg.com/@theia/application-manager/-/application-manager-1.9.0.tgz#fda3e92a43b59a00e3d69ba2ed894b0ae44f6fb8"
integrity sha512-dNXy0pO+Zzb4w9SoeE1PazOirJh/4mFtUPtPEjizKB0m5c5G3TN6CZ6OGutnjHPgxMRChf9HYoOyFHAL4KXCfw== integrity sha512-KJoK8+hhmv3mpnGlKZwqpPTQTDF73ZjRfVE6NyO1j+iS0k5UttVb29u63x8g95xgrJ3S8yOYvPoE9GuwW4KxFA==
dependencies: dependencies:
"@babel/core" "^7.10.0" "@babel/core" "^7.10.0"
"@babel/plugin-transform-classes" "^7.10.0" "@babel/plugin-transform-classes" "^7.10.0"
"@babel/plugin-transform-runtime" "^7.10.0" "@babel/plugin-transform-runtime" "^7.10.0"
"@babel/preset-env" "^7.10.0" "@babel/preset-env" "^7.10.0"
"@theia/application-package" "^1.8.0" "@theia/application-package" "^1.9.0"
"@theia/compression-webpack-plugin" "^3.0.0" "@theia/compression-webpack-plugin" "^3.0.0"
"@types/fs-extra" "^4.0.2" "@types/fs-extra" "^4.0.2"
"@types/webpack" "^4.41.2" "@types/webpack" "^4.41.2"
...@@ -1005,10 +1003,10 @@ ...@@ -1005,10 +1003,10 @@
webpack-cli "2.0.12" webpack-cli "2.0.12"
worker-loader "^1.1.1" worker-loader "^1.1.1"
"@theia/application-package@^1.8.0": "@theia/application-package@^1.9.0":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/application-package/-/application-package-1.8.0.tgz#087821f73e0f822d11ed400fd7c04df9917b755f" resolved "https://registry.yarnpkg.com/@theia/application-package/-/application-package-1.9.0.tgz#4abb831e125492f279f895775947cb2f76c0a547"
integrity sha512-fpTZLT46RCV2XMzYGpJMr7vzKTEOwK/m8jtDwap9ik+iiJ2rxJsc8COzuSnYcrWH0F6EvM1DcWBL30BK7UM3Ng== integrity sha512-QQGKLlFpfKFzD57LoajiTYze0x2Uk2bY4yALMgu6igz7vOKt6VDgahDKjtHT5jApM1hmZxuEIG4mQ2DT0pWa6A==
dependencies: dependencies:
"@types/fs-extra" "^4.0.2" "@types/fs-extra" "^4.0.2"
"@types/request" "^2.0.3" "@types/request" "^2.0.3"
...@@ -1022,23 +1020,23 @@ ...@@ -1022,23 +1020,23 @@
semver "^5.4.1" semver "^5.4.1"
write-json-file "^2.2.0" write-json-file "^2.2.0"
"@theia/callhierarchy@^1.8.0", "@theia/callhierarchy@latest": "@theia/callhierarchy@^1.9.0", "@theia/callhierarchy@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/callhierarchy/-/callhierarchy-1.8.0.tgz#88bfc6a4d90e61c74329bfce3f313b631da927cd" resolved "https://registry.yarnpkg.com/@theia/callhierarchy/-/callhierarchy-1.9.0.tgz#8c48e086c67e327f8cbde66f5e0d6d09b93cd411"
integrity sha512-wnHxelw5FXaW7Uz3D51cm5c/pJMN1ROpprp8e8nhnhsyHRM50B0cyKTCWFTR6mLIYqojXYn8h+IChJ9nyBSIlA== integrity sha512-VvU9f+ha5qhqdAaIwWnlSvAhzhXxUpTaSrRHyo4sH1drA/k50CM6PHzimp193eDFGRlhklOamTdFOGATTP7unw==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
ts-md5 "^1.2.2" ts-md5 "^1.2.2"
"@theia/cli@latest": "@theia/cli@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/cli/-/cli-1.8.0.tgz#34dd06ddaadd3ffc431a3f97f56c24b88f0bd397" resolved "https://registry.yarnpkg.com/@theia/cli/-/cli-1.9.0.tgz#9e2357719ced10fcf8184c8413aeed682c76f8c6"
integrity sha512-xckbi7wxfBL53lxTgHjKekp3ju+nUD/0H6UNhxmaZTLXd1NohNh7f16I/apjgulvjfkpwHQbfS3PJ3lVAJnzAg== integrity sha512-u1eHGs4kDiBanBQd9qz4B7JQyYG0bQxu1vNZRchF27MPbpaW9XDn/IJPIwzQJWhbGSR6DSPL7VO5rv3mfXdHHQ==
dependencies: dependencies:
"@theia/application-manager" "^1.8.0" "@theia/application-manager" "^1.9.0"
"@theia/application-package" "^1.8.0" "@theia/application-package" "^1.9.0"
"@types/chai" "^4.2.7" "@types/chai" "^4.2.7"
"@types/mkdirp" "^0.5.2" "@types/mkdirp" "^0.5.2"
"@types/mocha" "^5.2.7" "@types/mocha" "^5.2.7"
...@@ -1071,24 +1069,24 @@ ...@@ -1071,24 +1069,24 @@
serialize-javascript "^1.4.0" serialize-javascript "^1.4.0"
webpack-sources "^1.0.1" webpack-sources "^1.0.1"
"@theia/console@^1.8.0", "@theia/console@latest": "@theia/console@^1.9.0", "@theia/console@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/console/-/console-1.8.0.tgz#2b141a23140669e1cf46c6df2a75dc1ec44714a2" resolved "https://registry.yarnpkg.com/@theia/console/-/console-1.9.0.tgz#2ca826e091322683eb0851a5d1efc9e8270373f5"
integrity sha512-lKN2I15rjDrg1eI49xuaTnO40cuaWJLR1DiwMydmsitxaJ7zxpv2ZUqITY1xtacxZeIISHYOvax8w3c/w3qsOw== integrity sha512-kGxYj2mhslmuUTkmChQr5/JNjF9ZuiE2efM4sR1XfWg5i2+asF9xL6bs04CR/LqJjgMvA1tMXUYz+u6drtLU5Q==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
anser "^2.0.1" anser "^2.0.1"
"@theia/core@^1.8.0", "@theia/core@latest": "@theia/core@^1.9.0", "@theia/core@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/core/-/core-1.8.0.tgz#dc5d1a311635806e0c476aa73d0626b71f0f96fe" resolved "https://registry.yarnpkg.com/@theia/core/-/core-1.9.0.tgz#cd5264c7599f2d3b2f718aebca09df9e65234ced"
integrity sha512-v6e8OEhqQlOSS1Bv6UVifNqBN29Dzcvf55Hq8r/+iSHfRQ7SjNnVJwinF5xMpNwXYc2lBS3AiovNNekrpC/RGA== integrity sha512-spmD91IClwwwuBrvpxmAl5xzo6/S2c8L4/02JnQ+/pOdCw02QBy6ZLa9aZD3vo0N0ggUiIF2suima/JFqpdL0g==
dependencies: dependencies:
"@babel/runtime" "^7.10.0" "@babel/runtime" "^7.10.0"
"@phosphor/widgets" "^1.9.3" "@phosphor/widgets" "^1.9.3"
"@primer/octicons-react" "^9.0.0" "@primer/octicons-react" "^9.0.0"
"@theia/application-package" "^1.8.0" "@theia/application-package" "^1.9.0"
"@types/body-parser" "^1.16.4" "@types/body-parser" "^1.16.4"
"@types/cookie" "^0.3.3" "@types/cookie" "^0.3.3"
"@types/express" "^4.16.0" "@types/express" "^4.16.0"
...@@ -1108,7 +1106,7 @@ ...@@ -1108,7 +1106,7 @@
drivelist "^9.0.2" drivelist "^9.0.2"
es6-promise "^4.2.4" es6-promise "^4.2.4"
express "^4.16.3" express "^4.16.3"
file-icons-js "^1.0.3" file-icons-js "~1.0.3"
font-awesome "^4.7.0" font-awesome "^4.7.0"
fs-extra "^4.0.2" fs-extra "^4.0.2"
fuzzy "^0.1.3" fuzzy "^0.1.3"
...@@ -1127,7 +1125,7 @@ ...@@ -1127,7 +1125,7 @@
reflect-metadata "^0.1.10" reflect-metadata "^0.1.10"
route-parser "^0.0.5" route-parser "^0.0.5"
safer-buffer "^2.1.2" safer-buffer "^2.1.2"
vscode-languageserver-protocol "^3.15.3" vscode-languageserver-protocol "~3.15.3"
vscode-languageserver-types "^3.15.1" vscode-languageserver-types "^3.15.1"
vscode-uri "^2.1.1" vscode-uri "^2.1.1"
vscode-ws-jsonrpc "^0.2.0" vscode-ws-jsonrpc "^0.2.0"
...@@ -1144,26 +1142,26 @@ ...@@ -1144,26 +1142,26 @@
ajv "^6.5.3" ajv "^6.5.3"
lodash "^4.17.10" lodash "^4.17.10"
"@theia/debug@^1.8.0", "@theia/debug@latest": "@theia/debug@^1.9.0", "@theia/debug@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/debug/-/debug-1.8.0.tgz#2f589d1b6525b1dd44b683099ab0ab24cf19aa7c" resolved "https://registry.yarnpkg.com/@theia/debug/-/debug-1.9.0.tgz#9984b565061d13f7e0c474562df1cc12c4e0df1d"
integrity sha512-TecOK7cB2+4ctpgY8o7WS+mKBTnxd+xPVfu+OU1cmSvwYVo46k3eAd1C+yo0NIUs06iF7c9uisG+MeqzYzDMIg== integrity sha512-LiUVRjbHLZHYD7UVhCgtTNomQwFlOMXiQ/jDVH+ScVwQnoptfeY4mz0sFslpmvLTtIGV1722aRtgmMj6J5GM+g==
dependencies: dependencies:
"@theia/application-package" "^1.8.0" "@theia/application-package" "^1.9.0"
"@theia/console" "^1.8.0" "@theia/console" "^1.9.0"
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/markers" "^1.8.0" "@theia/markers" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@theia/output" "^1.8.0" "@theia/output" "^1.9.0"
"@theia/preferences" "^1.8.0" "@theia/preferences" "^1.9.0"
"@theia/process" "^1.8.0" "@theia/process" "^1.9.0"
"@theia/task" "^1.8.0" "@theia/task" "^1.9.0"
"@theia/terminal" "^1.8.0" "@theia/terminal" "^1.9.0"
"@theia/userstorage" "^1.8.0" "@theia/userstorage" "^1.9.0"
"@theia/variable-resolver" "^1.8.0" "@theia/variable-resolver" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
jsonc-parser "^2.2.0" jsonc-parser "^2.2.0"
mkdirp "^0.5.0" mkdirp "^0.5.0"
p-debounce "^2.1.0" p-debounce "^2.1.0"
...@@ -1173,43 +1171,43 @@ ...@@ -1173,43 +1171,43 @@
vscode-debugprotocol "^1.32.0" vscode-debugprotocol "^1.32.0"
"@theia/editor-preview@latest": "@theia/editor-preview@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/editor-preview/-/editor-preview-1.8.0.tgz#3d6552799528e7711c40ddcf1f4952055badc804" resolved "https://registry.yarnpkg.com/@theia/editor-preview/-/editor-preview-1.9.0.tgz#2e9e869dde725cbe59f3d50d6578cb49a9ecb055"
integrity sha512-aFBynXDYLyEsBQxd+yshgX2i68nDIEsLUu5106NUJwdsY/Bq0NedALFFFWrL4wdWWUf+hx5bJjNxkSRd5sZBEw== integrity sha512-kru8IDzwmdxWInu9Zdd3q3mioq7sZcg1NGq4c9pQW55C1E96HulhAs82UIdeEGrtW+Je25Fv2SAIM2178MXvjA==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/editor@^1.8.0", "@theia/editor@latest": "@theia/editor@^1.9.0", "@theia/editor@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/editor/-/editor-1.8.0.tgz#0c07d3db117d1f7cb95bbecdf57040d8a9d7c267" resolved "https://registry.yarnpkg.com/@theia/editor/-/editor-1.9.0.tgz#01d11f5f27ce32e495bc3075d07ae83ff83139af"
integrity sha512-hY+LyzBZM1JwYimII10KC7o/gB3BwQidvBo/+sLaFKw1DUDnCi+HQI6lpZM2LC+IKWhs6hn6Uh0tm/63LylynQ== integrity sha512-q6aa6dKQkB6AAbuXvOghBFDNdnYMETgUBWQvhR48Kg7VJjYKgzJ0tVyYMrR10CetUkVRysqKT1kg6wEsjZEeww==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/variable-resolver" "^1.8.0" "@theia/variable-resolver" "^1.9.0"
"@types/base64-arraybuffer" "0.1.0" "@types/base64-arraybuffer" "0.1.0"
base64-arraybuffer "^0.1.5" base64-arraybuffer "^0.1.5"
"@theia/file-search@^1.8.0", "@theia/file-search@latest": "@theia/file-search@^1.9.0", "@theia/file-search@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/file-search/-/file-search-1.8.0.tgz#a451975790f2c39cb60e4e840706fc6bb6c54904" resolved "https://registry.yarnpkg.com/@theia/file-search/-/file-search-1.9.0.tgz#32c138f1bac3645c032824ce4c65617846cc30d1"
integrity sha512-I3cjE86pVVcdj90e4fm5JgxIMEKLDGrfFbTMbcHM6CqqyNVqqKdiXtlMyX1bpt7yapzGzwooQJfhLc1Yie42Iw== integrity sha512-QrPZofFr1L51R4OutPzZ+ytXa5eEtWrmxruHjF3WDxlp9oLQN1Vk1bDlQYACiMQjHxaGyTPg2QwcEpL/IKaM4g==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/process" "^1.8.0" "@theia/process" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
fuzzy "^0.1.3" fuzzy "^0.1.3"
vscode-ripgrep "^1.2.4" vscode-ripgrep "^1.2.4"
"@theia/filesystem@^1.8.0", "@theia/filesystem@latest": "@theia/filesystem@^1.9.0", "@theia/filesystem@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/filesystem/-/filesystem-1.8.0.tgz#db76b0326f48ed4b7671adc2215fe9a35b0a5259" resolved "https://registry.yarnpkg.com/@theia/filesystem/-/filesystem-1.9.0.tgz#929b7cd7645b0122ebbe06c1eac3f7157cb886f3"
integrity sha512-+7dZKmFznM/EWQU+tYTDsAcj/ywDY3O3Y8CDxAu77Bo/8O6+UBbp2Pm5fOcqL2xGQ/8CLe03zmrSQ41/LMdSyQ== integrity sha512-130ciz34LIQTqG0Cc9Hi/s2iaMCYNZ2HvZV9BxVhdPp8UXuo4rO4EAq0AhvRoBdUTvEFtZNY3++GKnM7WNBy1w==
dependencies: dependencies:
"@theia/application-package" "^1.8.0" "@theia/application-package" "^1.9.0"
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@types/body-parser" "^1.17.0" "@types/body-parser" "^1.17.0"
"@types/rimraf" "^2.0.2" "@types/rimraf" "^2.0.2"
"@types/tar-fs" "^1.16.1" "@types/tar-fs" "^1.16.1"
...@@ -1224,28 +1222,28 @@ ...@@ -1224,28 +1222,28 @@
vscode-languageserver-textdocument "^1.0.1" vscode-languageserver-textdocument "^1.0.1"
"@theia/getting-started@latest": "@theia/getting-started@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/getting-started/-/getting-started-1.8.0.tgz#c506c5f3b358d4309902c5a10527e235678a20b4" resolved "https://registry.yarnpkg.com/@theia/getting-started/-/getting-started-1.9.0.tgz#73e73b166270cd0ecaae7bc1ee5197df61783c1a"
integrity sha512-pR7BTHkqarVoHvjO8nFHNsKoYrmskxrZMgvtFQzAmSLMtYry2DPWcfIPcGBucvJGLB9wWJ49wSn+AH4S1AeWsA== integrity sha512-QXd23sXCCYkV7wDOsgV0AHULApp/hfUa23dic1i9avjKoLC6jk96hoBfDpgRqUJWEpiNEzSQ69bbO2K3z/o2Wg==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/keymaps" "^1.8.0" "@theia/keymaps" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
"@theia/git@latest": "@theia/git@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/git/-/git-1.8.0.tgz#ce10757f4177684f0eae224aba3fa1acb22d2cc7" resolved "https://registry.yarnpkg.com/@theia/git/-/git-1.9.0.tgz#732b635531b3af1bf3a952dd7a31bbe2200ab231"
integrity sha512-WFJl1A7/fa0MwX1fg7hNuMPTzkWwd1UpdirH48jX2CKYJ2/MsK8IJWv1SxqtbH+mkFMu4HhzZ9nFtzMbxXd+Tg== integrity sha512-IQNmPtAHtygvIi6pq212APK+N6WPobn2HIcnPJNCeUrKe2zaLIKiJV1B1HYh5QHMPV/tse/+3+GSmpOcOl8t3Q==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@theia/navigator" "^1.8.0" "@theia/navigator" "^1.9.0"
"@theia/scm" "^1.8.0" "@theia/scm" "^1.9.0"
"@theia/scm-extra" "^1.8.0" "@theia/scm-extra" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
"@types/diff" "^3.2.2" "@types/diff" "^3.2.2"
"@types/p-queue" "^2.3.1" "@types/p-queue" "^2.3.1"
diff "^3.4.0" diff "^3.4.0"
...@@ -1257,79 +1255,81 @@ ...@@ -1257,79 +1255,81 @@
p-queue "^2.4.2" p-queue "^2.4.2"
ts-md5 "^1.2.2" ts-md5 "^1.2.2"
"@theia/keymaps@^1.8.0", "@theia/keymaps@latest": "@theia/keymaps@^1.9.0", "@theia/keymaps@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/keymaps/-/keymaps-1.8.0.tgz#4ecdd4b7e8b2eaec15f5b8e313cbd37cb3e5a057" resolved "https://registry.yarnpkg.com/@theia/keymaps/-/keymaps-1.9.0.tgz#37dcf69f15bf6339552d1c811b7475db0dc9b2d3"
integrity sha512-1J4KqXvoAjDEkR+WO9D9ntm6A8R1FUQKEhmRaqpIxwVnuXqxE9sEH9gLagXwErrzoHqLr9OAEM34YWRgjst8NQ== integrity sha512-Rm+7GS5cjZWYfG9h6vZeXRsDdSfSpizqyg/jSNCsPBYfqJ6tygDYfisb/oQpb8SmZvOk3YoUog8rMj82mIsNGg==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@theia/userstorage" "^1.8.0" "@theia/userstorage" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
"@types/lodash.debounce" "4.0.3" "@types/lodash.debounce" "4.0.3"
ajv "^6.5.3" ajv "^6.5.3"
fuzzy "^0.1.3" fuzzy "^0.1.3"
jsonc-parser "^2.2.0" jsonc-parser "^2.2.0"
lodash.debounce "^4.0.8" lodash.debounce "^4.0.8"
"@theia/markers@^1.8.0", "@theia/markers@latest": "@theia/markers@^1.9.0", "@theia/markers@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/markers/-/markers-1.8.0.tgz#cdbd41607a6bf7f9441d4274f1301d4e5b1b15b5" resolved "https://registry.yarnpkg.com/@theia/markers/-/markers-1.9.0.tgz#df1ef2db0f29617880b5a5e61f943e31d4a84ccf"
integrity sha512-hyw6prv6JoTey6N14FzG7Dti/fAc9FbCtKPizGY1UvZFmaY/ibpUoj3o5iRSui/qNg2VOGLA+schgqKZOPQMjA== integrity sha512-W4sEZ+K0mlgBOyZS1EdJdXpWBNPtvWDHXqXSYNvF6Ti9zcHt8+t+CvSc/g4DXqnwwrqmNJfGP/jKAg/TLlW4rg==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/navigator" "^1.8.0" "@theia/navigator" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
"@theia/messages@^1.8.0", "@theia/messages@latest": "@theia/messages@^1.9.0", "@theia/messages@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/messages/-/messages-1.8.0.tgz#b950de2f94cf307fa44be4d279c0ccbe01609a13" resolved "https://registry.yarnpkg.com/@theia/messages/-/messages-1.9.0.tgz#767155ed79c993b07c70b0601cff9c39790aa5b1"
integrity sha512-GfSPkSDv5IazgRzf9N9JByeP6DO/QpAiwCY3N+kntedO47EUQF9B9vY+KiWZVsm+K0Z/lKnTfxoD6fcD+GxPPw== integrity sha512-lZHrE2rjIFeB80mHkNBatp/ICYFRKHMTVnden+TGZ4a4PtwqjN4fY93QtJgDSpo7bLHIn7iLqB1I1jDSO9Ta4Q==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
lodash.throttle "^4.1.1" lodash.throttle "^4.1.1"
markdown-it "^8.4.0" markdown-it "^8.4.0"
react-perfect-scrollbar "^1.5.3" react-perfect-scrollbar "^1.5.3"
ts-md5 "^1.2.2" ts-md5 "^1.2.2"
"@theia/metrics@latest": "@theia/metrics@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/metrics/-/metrics-1.8.0.tgz#abb5474c1c7b7fa016cce2cb3cf7be69b476b1cf" resolved "https://registry.yarnpkg.com/@theia/metrics/-/metrics-1.9.0.tgz#de7326f9bf2665705df54dbe67b660ecc9a7f407"
integrity sha512-Rl4F5iS8r5IaBn7h8GneluGct+uXEt33T2G24W67Rmpl7OY4xd2z1OkQN2AO88fE5PIHHvqVb0rrxAGwNygH5w== integrity sha512-Ri9l30UDsfW4HW/SHzpfMYlAZMyMKdAN+pUMJvjIc6+t/6+qLpE/ouwxFssWyQ4IGgeMSFmaM/ijBzTHaIJ7kg==
dependencies: dependencies:
"@theia/application-package" "^1.8.0" "@theia/application-package" "^1.9.0"
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
prom-client "^10.2.0" prom-client "^10.2.0"
"@theia/mini-browser@^1.8.0", "@theia/mini-browser@latest": "@theia/mini-browser@^1.9.0", "@theia/mini-browser@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/mini-browser/-/mini-browser-1.8.0.tgz#f8e77d3fc4d9af671c8c33578fe988efc02780e2" resolved "https://registry.yarnpkg.com/@theia/mini-browser/-/mini-browser-1.9.0.tgz#60a2108de5558116c5813d60ba7eb15642a5cece"
integrity sha512-r/elEFBW4D6Fm/sLbrtE31DnKXvdwrBqcWdaJztUUtXDhpa8VCp5+NDcSMYw9Xbf8Osbq/7Fw10J14CRpsNBKA== integrity sha512-lP4Y73/Fb8bswOGpLV6ZrNWABBJlh9WmiZnhZZUUjcIIHbGQdyvsoHBs/pXSgEeeBtsP4158KHRf2HauOJJTgQ==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@types/mime-types" "^2.1.0" "@types/mime-types" "^2.1.0"
mime-types "^2.1.18" mime-types "^2.1.18"
pdfobject "^2.0.201604172" pdfobject "^2.0.201604172"
uuid "^8.0.0"
vhost "^3.0.2"
"@theia/monaco-editor-core@^0.20.0": "@theia/monaco-editor-core@^0.20.0":
version "0.20.0" version "0.20.0"
resolved "https://registry.yarnpkg.com/@theia/monaco-editor-core/-/monaco-editor-core-0.20.0.tgz#0f3cdfd6d1278bbcc3df0224471fc967a4d901c5" resolved "https://registry.yarnpkg.com/@theia/monaco-editor-core/-/monaco-editor-core-0.20.0.tgz#0f3cdfd6d1278bbcc3df0224471fc967a4d901c5"
integrity sha512-6QDOrZRW3dE0RgyD/hXMlVla49ACNjwIX+u9+i/qY+OqaZ1u/QdgdnHy4QO6g4J0lQCyr7nXgqF1BAc+Xbxx2g== integrity sha512-6QDOrZRW3dE0RgyD/hXMlVla49ACNjwIX+u9+i/qY+OqaZ1u/QdgdnHy4QO6g4J0lQCyr7nXgqF1BAc+Xbxx2g==
"@theia/monaco@^1.8.0", "@theia/monaco@latest": "@theia/monaco@^1.9.0", "@theia/monaco@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/monaco/-/monaco-1.8.0.tgz#35c6286ff0ea3067edb825742e847899d1b1183b" resolved "https://registry.yarnpkg.com/@theia/monaco/-/monaco-1.9.0.tgz#c8fc6ec89fa93fbb8748cbf101f91071ddea1e58"
integrity sha512-gCAycSH15lFqT2v9ixOv5oNQkUm2AyiKFGdZQJd2cJwKfIRO9cFUOqjXHPKhiena2PSo22lAAiSXMbxhKWzJhA== integrity sha512-u9vyvKnaQ/px4Xm+CvHavdjJxdHDyyRKzQh8q9nEOs2JfGXUbMjpb7VFuen8elXjNaivXbVT/OqNC3VJvRnPFw==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/markers" "^1.8.0" "@theia/markers" "^1.9.0"
"@theia/monaco-editor-core" "^0.20.0" "@theia/monaco-editor-core" "^0.20.0"
"@theia/outline-view" "^1.8.0" "@theia/outline-view" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
deepmerge "2.0.1" deepmerge "2.0.1"
fast-plist "^0.1.2" fast-plist "^0.1.2"
idb "^4.0.5" idb "^4.0.5"
...@@ -1337,14 +1337,14 @@ ...@@ -1337,14 +1337,14 @@
onigasm "^2.2.0" onigasm "^2.2.0"
vscode-textmate "^4.4.0" vscode-textmate "^4.4.0"
"@theia/navigator@^1.8.0", "@theia/navigator@latest": "@theia/navigator@^1.9.0", "@theia/navigator@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/navigator/-/navigator-1.8.0.tgz#877833624311b5aad575acdf93d41a0091acb4bf" resolved "https://registry.yarnpkg.com/@theia/navigator/-/navigator-1.9.0.tgz#08da387dc7925f02bcafb658cb16b9f777caca7a"
integrity sha512-K4uLTcyGZmH3DeX/kNNpHI1BTIpvvk92xX7zytuxexzmBRRS+7tTKk/3nSPTmO2oCJgeVxdTkKLJUisEFcOIzA== integrity sha512-B1pxx7PNrczYAVjuYklJh0tttko5sgakN51lpfVsJ+iGx2neijBhwtwMcnl4TBxQhMNoy31BH9ofSyee1SSPmA==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
fuzzy "^0.1.3" fuzzy "^0.1.3"
minimatch "^3.0.4" minimatch "^3.0.4"
...@@ -1355,69 +1355,66 @@ ...@@ -1355,69 +1355,66 @@
dependencies: dependencies:
nan "^2.14.0" nan "^2.14.0"
"@theia/outline-view@^1.8.0", "@theia/outline-view@latest": "@theia/outline-view@^1.9.0", "@theia/outline-view@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/outline-view/-/outline-view-1.8.0.tgz#63393cc53da435a0856e0c70741fb027819fc28e" resolved "https://registry.yarnpkg.com/@theia/outline-view/-/outline-view-1.9.0.tgz#f9ece3ff2d8307ad1516dc17743671e72157696d"
integrity sha512-X5sC7kF4KMyLHxMCMKRJnipsw5Egyr/ymDRi2sshAtgE53cV6jLvKJmt0WoxA8StLeYcAkI5WzVFuwcXhZH3Kw== integrity sha512-/Auf8quB/Tj4gLXT5w71jYwD6lXiBMaV57fYXjXHR3gJOm9FtBkLpmHeotttzWjbqrNlmZY5beiEh0BlIF9FXw==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/output@^1.8.0", "@theia/output@latest": "@theia/output@^1.9.0", "@theia/output@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/output/-/output-1.8.0.tgz#927d209ebf5f882258f0c1c63957a1eeb2edebba" resolved "https://registry.yarnpkg.com/@theia/output/-/output-1.9.0.tgz#858a1c50eab082cb9e44d6e022f3d9a5948f10e5"
integrity sha512-8cldJTyPzorbSPaJ1fidmxJAgw+0mApb98PCGT6oDCD0JDFtdErweAtgsXtSbpDX7+ROORmbQeiYd5EeqIF8pg== integrity sha512-BdRMCZgdPdKzqMuM7T0O0jrE71960qU28+nKGITjVDWMukXjw0e5my7xxSmz5UZK4CX7VLd1mgMWXN8JQRmqEQ==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@types/p-queue" "^2.3.1" "@types/p-queue" "^2.3.1"
p-queue "^2.4.2" p-queue "^2.4.2"
"@theia/plugin-ext-vscode@^1.8.0", "@theia/plugin-ext-vscode@latest": "@theia/plugin-ext-vscode@^1.9.0", "@theia/plugin-ext-vscode@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/plugin-ext-vscode/-/plugin-ext-vscode-1.8.0.tgz#a4ce3cd0598078d248d4e0c9d676004cc55bdd7b" resolved "https://registry.yarnpkg.com/@theia/plugin-ext-vscode/-/plugin-ext-vscode-1.9.0.tgz#37532477cac418dcfc90573b602d2d7e0f2ba245"
integrity sha512-fnB1JhJuZ1VboknP4ZL4hGAM96hJ6zpr21ZyPYhHstdXG7F13sntpObPBkqlHzdRoald3+eej0lSfdL/NESxDA== integrity sha512-cDLfL6Q6P7kdBNX27wPI9hUfTCQ/hbbh3Jx+dKAD3kD+WYs8RktTamSCb+Dtw8xZI1L6h3DYyXSX/lQz3iN2Aw==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@theia/plugin" "^1.8.0" "@theia/plugin" "^1.9.0"
"@theia/plugin-ext" "^1.8.0" "@theia/plugin-ext" "^1.9.0"
"@theia/userstorage" "^1.8.0" "@theia/userstorage" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
"@types/request" "^2.0.3" "@types/request" "^2.0.3"
filenamify "^4.1.0" filenamify "^4.1.0"
request "^2.82.0" request "^2.82.0"
"@theia/plugin-ext@^1.8.0", "@theia/plugin-ext@latest": "@theia/plugin-ext@^1.9.0", "@theia/plugin-ext@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/plugin-ext/-/plugin-ext-1.8.0.tgz#0d90d88faa46057dc05527946b6126e2ef031f5d" resolved "https://registry.yarnpkg.com/@theia/plugin-ext/-/plugin-ext-1.9.0.tgz#167efc731440ebdbeab8831bd2a24815165e6435"
integrity sha512-FwOSspt9nmteLR7bPGk0FjdfZGDIP2Sq4b35gmPr5Qd3M+E5h1lKah/EBDoBRqdWH+VzEsVcpLtiA6+ygg0xPg== integrity sha512-E8PO7mFEZ1YGcl1dO50IZYgEFbh48A3Cq9lWK1JpkV1m86iziMwuZwH3/HosXd5uEKZxP5E6Ao35Zy4B552Ehw==
dependencies: dependencies:
"@theia/callhierarchy" "^1.8.0" "@theia/callhierarchy" "^1.9.0"
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/debug" "^1.8.0" "@theia/debug" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/file-search" "^1.8.0" "@theia/file-search" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/markers" "^1.8.0" "@theia/markers" "^1.9.0"
"@theia/messages" "^1.8.0" "@theia/messages" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@theia/navigator" "^1.8.0" "@theia/navigator" "^1.9.0"
"@theia/output" "^1.8.0" "@theia/output" "^1.9.0"
"@theia/plugin" "^1.8.0" "@theia/plugin" "^1.9.0"
"@theia/preferences" "^1.8.0" "@theia/preferences" "^1.9.0"
"@theia/scm" "^1.8.0" "@theia/scm" "^1.9.0"
"@theia/search-in-workspace" "^1.8.0" "@theia/search-in-workspace" "^1.9.0"
"@theia/task" "^1.8.0" "@theia/task" "^1.9.0"
"@theia/terminal" "^1.8.0" "@theia/terminal" "^1.9.0"
"@theia/timeline" "^1.8.0" "@theia/timeline" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
"@types/connect" "^3.4.32"
"@types/dompurify" "^2.0.2" "@types/dompurify" "^2.0.2"
"@types/mime" "^2.0.1" "@types/mime" "^2.0.1"
"@types/serve-static" "^1.13.3"
connect "^3.7.0"
decompress "^4.2.1" decompress "^4.2.1"
dompurify "^2.0.11" dompurify "^2.0.11"
escape-html "^1.0.3" escape-html "^1.0.3"
...@@ -1428,39 +1425,38 @@ ...@@ -1428,39 +1425,38 @@
mime "^2.4.4" mime "^2.4.4"
ps-tree "^1.2.0" ps-tree "^1.2.0"
request "^2.82.0" request "^2.82.0"
serve-static "^1.14.1"
uuid "^8.0.0" uuid "^8.0.0"
vhost "^3.0.2" vhost "^3.0.2"
vscode-debugprotocol "^1.32.0" vscode-debugprotocol "^1.32.0"
vscode-textmate "^4.0.1" vscode-textmate "^4.0.1"
"@theia/plugin@^1.8.0", "@theia/plugin@latest": "@theia/plugin@^1.9.0", "@theia/plugin@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/plugin/-/plugin-1.8.0.tgz#b3a2a5d874a4105f0d20ff333818b72f8e966597" resolved "https://registry.yarnpkg.com/@theia/plugin/-/plugin-1.9.0.tgz#b6e0e528a12195bbee1c1e47d1e727fb0a167f87"
integrity sha512-/nrX2prLpJgKcecH1xdg+v2HJcxaePbScA7k/Z/t8outKZatO0odX2F04wAWgwOLfDLq6POyuyGQ/L9XExsd/Q== integrity sha512-MqsbjcAEd2ID6HQylr6pWMPH2SuzdrXWxg3aMnkL8eejXzur/tZCjGCoPon9CKS1yIzzuuOtiRnAqBVkRxF0Uw==
"@theia/preferences@^1.8.0", "@theia/preferences@latest": "@theia/preferences@^1.9.0", "@theia/preferences@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/preferences/-/preferences-1.8.0.tgz#fecf99ac290f778f0f8f648f3da259e96fedd324" resolved "https://registry.yarnpkg.com/@theia/preferences/-/preferences-1.9.0.tgz#e3cf507fe7a300bf3ef7ff913bd77de5938ad157"
integrity sha512-AuK9jKzQg5fWG8iuJNksFCAMsVRg4/01XELanOCDOeegPW7fwqz+SSFJMYN1e/Dhw762u+aVpWy39OmBV8qVfA== integrity sha512-mKRkNaCGSZsYuw2WV39NVQdnlX3W1n0smAJh9nIG9NhDjGUrV728d9wCZYo8Ru+t6kwFH8QXEVVaVe3XQ3u9VA==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@theia/userstorage" "^1.8.0" "@theia/userstorage" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
jsonc-parser "^2.2.0" jsonc-parser "^2.2.0"
"@theia/preview@latest": "@theia/preview@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/preview/-/preview-1.8.0.tgz#3664b1b9b4eb3ac0506f6144e0d5d4e424e8ba53" resolved "https://registry.yarnpkg.com/@theia/preview/-/preview-1.9.0.tgz#cb61bbeda2693689cbf4c874a0d64171326d2c88"
integrity sha512-UiHp3qPnncG/+0b/p5//aW5fSn3U3qTyXtFepMqlOU+uGAqhxLfSKAmGx/kMKerP2nqHFyGxxptbJRZR9bnXmg== integrity sha512-/dicR9RI3k9O0oFGlsd8u9n2EQPVf6yeEbX2N7Qe+ofod5yGaVdekvQWsVkT7qf5cL/fq1/KenYtOn5E5U6A2Q==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/mini-browser" "^1.8.0" "@theia/mini-browser" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@types/dompurify" "^2.0.2" "@types/dompurify" "^2.0.2"
"@types/highlight.js" "^9.12.2" "@types/highlight.js" "^9.12.2"
"@types/markdown-it" "*" "@types/markdown-it" "*"
...@@ -1470,127 +1466,127 @@ ...@@ -1470,127 +1466,127 @@
markdown-it "^8.4.0" markdown-it "^8.4.0"
markdown-it-anchor "~5.0.0" markdown-it-anchor "~5.0.0"
"@theia/process@^1.8.0", "@theia/process@latest": "@theia/process@^1.9.0", "@theia/process@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/process/-/process-1.8.0.tgz#9285534182d90fcc6602d02d6d21e3293dfd2902" resolved "https://registry.yarnpkg.com/@theia/process/-/process-1.9.0.tgz#4bbbb341ec299d04894af9029b690b667f9cf85e"
integrity sha512-PfbaXPJhHMyDoEbk7WRWOj8otbjNOgZGLCSxgfr3tGMOlN8ZPwcYZuRk9+McfbfcL6IFbA3O6FjGc1K4BKEcmg== integrity sha512-pnPGJw3DWDXEWWPXtC3NCibb3Wu8i30n8QQa87Va+qaSnaCwWWM3IpqR4cfzyLZcNCTcHgLhbcLikd70ZK+f4A==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/node-pty" "0.9.0-theia.6" "@theia/node-pty" "0.9.0-theia.6"
string-argv "^0.1.1" string-argv "^0.1.1"
"@theia/scm-extra@^1.8.0": "@theia/scm-extra@^1.9.0":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/scm-extra/-/scm-extra-1.8.0.tgz#923aff6ff8c625c7cbc8652344e6bcd995e2ea75" resolved "https://registry.yarnpkg.com/@theia/scm-extra/-/scm-extra-1.9.0.tgz#a864acf24a2687c8b198d687ec1e18ad40d12190"
integrity sha512-xAsS+/b7F9wvGLgifb9DnCYrlc96A/Y9ftfgu+v11RpAMA1SkT3MA9O9qNOvkfJWusLbbJRTG6moA7qqVQLkaQ== integrity sha512-SxTdGe/0RTvBMPlxTRG9qi2cwmqR0B0cUv/8iAFGfgNALBBqd0OWQbunWcQNJHD2aBWPRutbOr90nUbo9Y/HWg==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/navigator" "^1.8.0" "@theia/navigator" "^1.9.0"
"@theia/scm" "^1.8.0" "@theia/scm" "^1.9.0"
"@theia/scm@^1.8.0", "@theia/scm@latest": "@theia/scm@^1.9.0", "@theia/scm@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/scm/-/scm-1.8.0.tgz#6bd7754f2b51c30bcecfe6c9fc1f37c49b257c29" resolved "https://registry.yarnpkg.com/@theia/scm/-/scm-1.9.0.tgz#34218ac6cd75a6d05647157b89af620adde7d524"
integrity sha512-MbIlW7vwhm61c89n835ZcrmHttORw4kdgPz/30g5Rn8CxZJK1pygKmGeMDp4j4YkRTYJ2hhpPcP902PZbZIGfQ== integrity sha512-MchW7+61lp5o90rdLV1vsiz+pYdvCd7Pu73MLwjMDEQ6MIsVIk/4R51HZrNFf+fTaJ44Y/H/5lAhj42TV1/osw==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/navigator" "^1.8.0" "@theia/navigator" "^1.9.0"
"@types/diff" "^3.2.2" "@types/diff" "^3.2.2"
diff "^3.4.0" diff "^3.4.0"
p-debounce "^2.1.0" p-debounce "^2.1.0"
react-autosize-textarea "^7.0.0" react-autosize-textarea "^7.0.0"
ts-md5 "^1.2.2" ts-md5 "^1.2.2"
"@theia/search-in-workspace@^1.8.0", "@theia/search-in-workspace@latest": "@theia/search-in-workspace@^1.9.0", "@theia/search-in-workspace@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/search-in-workspace/-/search-in-workspace-1.8.0.tgz#eccb408eb99b1dcacef2a71fa2e410d4a4807a6a" resolved "https://registry.yarnpkg.com/@theia/search-in-workspace/-/search-in-workspace-1.9.0.tgz#03d85c33199c08ed39bf783e4d0d088ccfe32bef"
integrity sha512-pJNqHzPqb83nNtxcP0ubN4AyB2XFV+Y8Zo2HbCKxtLmtFUjUHZ+OykpjR88znQfe/WeRfQlKBSnrep4cEypXng== integrity sha512-Q4FoqILG5/j8HU1AkgRXwdAuabN0t15a6Pkoi8hB3eKyM/CUM2t8+s8z3jW+CgngpIRqvUdHfg0qq+qBSa8x4A==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/navigator" "^1.8.0" "@theia/navigator" "^1.9.0"
"@theia/process" "^1.8.0" "@theia/process" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
minimatch "^3.0.4" minimatch "^3.0.4"
vscode-ripgrep "^1.2.4" vscode-ripgrep "^1.2.4"
"@theia/task@^1.8.0", "@theia/task@latest": "@theia/task@^1.9.0", "@theia/task@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/task/-/task-1.8.0.tgz#8741b7308318977736c28f2d60486ab6f8e7deca" resolved "https://registry.yarnpkg.com/@theia/task/-/task-1.9.0.tgz#605aaa834f8b48ba48a8f80d447af21a3e9b3120"
integrity sha512-V9MRCGjWPLcvVsp4pFVl0GLYKDj+syAZT5YVNt7BdZ1utsNzqd/RoPZD1cJ48pb5F2dTbupVkGMfeM9RxJRlFQ== integrity sha512-SOdNYzgk7kOECMC5aQsGVz2hiXoZONWl0hJtN6RirlqAPNIK/8JWmOR6697I2TRf3GU1g8TcKpiICTgRj47R1A==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/markers" "^1.8.0" "@theia/markers" "^1.9.0"
"@theia/monaco" "^1.8.0" "@theia/monaco" "^1.9.0"
"@theia/preferences" "^1.8.0" "@theia/preferences" "^1.9.0"
"@theia/process" "^1.8.0" "@theia/process" "^1.9.0"
"@theia/terminal" "^1.8.0" "@theia/terminal" "^1.9.0"
"@theia/variable-resolver" "^1.8.0" "@theia/variable-resolver" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
ajv "^6.5.3" ajv "^6.5.3"
jsonc-parser "^2.2.0" jsonc-parser "^2.2.0"
p-debounce "^2.1.0" p-debounce "^2.1.0"
"@theia/terminal@^1.8.0", "@theia/terminal@latest": "@theia/terminal@^1.9.0", "@theia/terminal@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/terminal/-/terminal-1.8.0.tgz#f44c5991b7643b1aab10acb00c1a8a33256e37d3" resolved "https://registry.yarnpkg.com/@theia/terminal/-/terminal-1.9.0.tgz#68472f6e0858b9c0ed155a937f0fc859570956d3"
integrity sha512-iQJnovTn6HKvO3PJbcD6bmadHhu7oYjzvAn2fKpxmcdTiGitEjdFzP0YeYIw/fAkvRPvUJzLHyBaGZ49ezQ0Dg== integrity sha512-xAUaLhwzNnkyc2nDh1LnezjCGsfCSChSE4yFQB+sukPVJEs+BlOO2L7odg0A+tcVeZVrR+DB72EWpvkq6h5DEQ==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/process" "^1.8.0" "@theia/process" "^1.9.0"
"@theia/workspace" "^1.8.0" "@theia/workspace" "^1.9.0"
xterm "^4.4.0" xterm "^4.4.0"
xterm-addon-fit "^0.3.0" xterm-addon-fit "^0.3.0"
xterm-addon-search "^0.5.0" xterm-addon-search "^0.5.0"
"@theia/timeline@^1.8.0": "@theia/timeline@^1.9.0":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/timeline/-/timeline-1.8.0.tgz#d07ddd5718eee68dfc238210802ce596a29d7ccb" resolved "https://registry.yarnpkg.com/@theia/timeline/-/timeline-1.9.0.tgz#cbaca3a443d133a39b1a6f917bc292ad315d0c2d"
integrity sha512-/kDhxHX070yFGUTeYo7hVMN+HOmRQNQNGqYS/IY8v8CqeLNXN+qq0JkXJDekpSdK6XIKPG26IaARbHtayATxnA== integrity sha512-yhfgwneJgBfRvRZmFsp0di+w/1IX9ONd3p9IXjDUjT0WyD21qEUnznJS9pN6XiZPPm6jsznYpj3Il4Fl65tqIg==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/typehierarchy@latest": "@theia/typehierarchy@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/typehierarchy/-/typehierarchy-1.8.0.tgz#1babb4c4018d2f207a5ed13d161745b55671901b" resolved "https://registry.yarnpkg.com/@theia/typehierarchy/-/typehierarchy-1.9.0.tgz#428ed1e005fbb3380e181a783e10c48340ee3790"
integrity sha512-6zPDI5RezLHAQnlN1CzT++nLS87+o7RI7aPJH+L5vVoMAfHYg74oeWHqkZ9fENF60q+5uY4SA2SLq2kr+Vwekg== integrity sha512-w9k/Llhtx6Ps+FNl/9CQSz/JWfCy6b/lX8uUzpg3jkY/7OquiSNz7iFAI5BVKYdf8CLj0nxuLvy+geUZusfwXw==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/editor" "^1.8.0" "@theia/editor" "^1.9.0"
"@types/uuid" "^7.0.3" "@types/uuid" "^7.0.3"
uuid "^8.0.0" uuid "^8.0.0"
"@theia/userstorage@^1.8.0", "@theia/userstorage@latest": "@theia/userstorage@^1.9.0", "@theia/userstorage@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/userstorage/-/userstorage-1.8.0.tgz#5bdaafbd7b816d3564205170b686b704005db72f" resolved "https://registry.yarnpkg.com/@theia/userstorage/-/userstorage-1.9.0.tgz#84808790f4d56d61f79e6a6ed2dbe609e60aa1f8"
integrity sha512-1F/VuSPd7yQaiebey2hIcaz+jPPVyidfhSEK64BrsmkmflRWALg2hwfFFu2RC1FiQ0K5L62cjJ1T39oL93NJqw== integrity sha512-bOjtOXfn1EAW7Mud7HSbYpDgOjLem8GKkev78s3iR5Hyp7/UZMKcBCEPWUNpzgR/27XSl6NoUR4uSWM6s/0Sgg==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/variable-resolver@^1.8.0", "@theia/variable-resolver@latest": "@theia/variable-resolver@^1.9.0", "@theia/variable-resolver@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/variable-resolver/-/variable-resolver-1.8.0.tgz#884f3ef4490f90eee8543c4d1f7e8cae361e303a" resolved "https://registry.yarnpkg.com/@theia/variable-resolver/-/variable-resolver-1.9.0.tgz#ac8f55d89ca790a97434f682d6a2fde3bab6f07a"
integrity sha512-T1ylznZDO4Eb0/mpF1ddEt1ZDJu+9yFjOmpvLxvpvtXE7tGNQwnKm7p4BgL3ZYUuW6NX6HodJrsJSJEo+W28fg== integrity sha512-t0RtkNX+0E/upGuTqC5qcPh0kSInMr3KKfZu42BZV6DF8rNYqi0SQDfl+5YSsROaAdnG5Ny2wnYkLahnWuglFw==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/vsx-registry@latest": "@theia/vsx-registry@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/vsx-registry/-/vsx-registry-1.8.0.tgz#8d72845932162410108a109cd6096e6bb327a533" resolved "https://registry.yarnpkg.com/@theia/vsx-registry/-/vsx-registry-1.9.0.tgz#6d48f1ab466ab5741eead2bc19c90fc91cbf167e"
integrity sha512-k9xOYk0Xq/8Squj2F0XThpylpwjGi39WGte7WvK5CvtN8Z1rWT3EDEXFHk9BGXltznVeMPt+oIxz8I32G6Jm5Q== integrity sha512-TQNM9NHyP0uDiuS13ZI1R1kZlgLndDwSfq7sWOD7gshrTeFechlrNFDHD7b/WWGPA7WTncTtpfSvPfK65gZy0g==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/plugin-ext-vscode" "^1.8.0" "@theia/plugin-ext-vscode" "^1.9.0"
"@types/bent" "^7.0.1" "@types/bent" "^7.0.1"
"@types/sanitize-html" "^1.13.31" "@types/sanitize-html" "^1.13.31"
"@types/showdown" "^1.7.1" "@types/showdown" "^1.7.1"
...@@ -1602,14 +1598,14 @@ ...@@ -1602,14 +1598,14 @@
showdown "^1.9.1" showdown "^1.9.1"
uuid "^8.0.0" uuid "^8.0.0"
"@theia/workspace@^1.8.0", "@theia/workspace@latest": "@theia/workspace@^1.9.0", "@theia/workspace@latest":
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/@theia/workspace/-/workspace-1.8.0.tgz#e8b40d1a1b3acaf1fb6ce38ea3e4c9685620e5db" resolved "https://registry.yarnpkg.com/@theia/workspace/-/workspace-1.9.0.tgz#a1f3f998da870fbb710fe8929ac3c1c2bff8bc75"
integrity sha512-s3pPqoo2cUVM4dfcvwP+AV0xxqK7Xq6y1NfIKNmx6tynykISK/HM68ikAzrdSHvWXc+4mYEB5CoqcPUNDhV6xg== integrity sha512-cazTHaSQE8voTs4TSoRaypa8cjPdVUy7iMF3bmX/i1t2oDStkcqLSCICAs90VZNyTSfCwdOYGxMRQsS+QyETcw==
dependencies: dependencies:
"@theia/core" "^1.8.0" "@theia/core" "^1.9.0"
"@theia/filesystem" "^1.8.0" "@theia/filesystem" "^1.9.0"
"@theia/variable-resolver" "^1.8.0" "@theia/variable-resolver" "^1.9.0"
ajv "^6.5.3" ajv "^6.5.3"
jsonc-parser "^2.2.0" jsonc-parser "^2.2.0"
moment "2.24.0" moment "2.24.0"
...@@ -1650,10 +1646,10 @@ ...@@ -1650,10 +1646,10 @@
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.14.tgz#44d2dd0b5de6185089375d976b4ec5caf6861193" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.14.tgz#44d2dd0b5de6185089375d976b4ec5caf6861193"
integrity sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ== integrity sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==
"@types/connect@*", "@types/connect@^3.4.32": "@types/connect@*":
version "3.4.33" version "3.4.34"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901"
integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== integrity sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
...@@ -1680,9 +1676,9 @@ ...@@ -1680,9 +1676,9 @@
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
"@types/express-serve-static-core@*": "@types/express-serve-static-core@*":
version "4.17.14" version "4.17.17"
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.14.tgz#cabf91debeeb3cb04b798e2cff908864e89b6106" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.17.tgz#6ba02465165b6c9c3d8db3a28def6b16fc9b70f5"
integrity sha512-uFTLwu94TfUFMToXNgRZikwPuZdOtDgs3syBtAIr/OXorL1kJqUJT9qCLnRZ5KBOWfZQikQ2xKgR2tnDj1OgDA== integrity sha512-YYlVaCni5dnHc+bLZfY908IG1+x5xuibKZMGv8srKkvtul3wUuanYvpIj9GXXoWkQbaAdR+kgX46IETKUALWNQ==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/qs" "*" "@types/qs" "*"
...@@ -1724,9 +1720,9 @@ ...@@ -1724,9 +1720,9 @@
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
"@types/linkify-it@*": "@types/linkify-it@*":
version "2.1.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-2.1.0.tgz#ea3dd64c4805597311790b61e872cbd1ed2cd806" resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.0.tgz#c0ca4c253664492dbf47a646f31cfd483a6bbc95"
integrity sha512-Q7DYAOi9O/+cLLhdaSvKdaumWyHbm7HAk/bFwwyTuU0arR5yyCeW5GOoqt4tJTpDRxhpx9Q8kQL6vMpuw9hDSw== integrity sha512-x9OaQQTb1N2hPZ/LWJsqushexDvz7NgzuZxiRmZio44WPuolTZNHDBCrOxCzRVOMwamJRO2dWax5NbygOf1OTQ==
"@types/lodash.debounce@4.0.3": "@types/lodash.debounce@4.0.3":
version "4.0.3" version "4.0.3"
...@@ -1755,14 +1751,13 @@ ...@@ -1755,14 +1751,13 @@
"@types/markdown-it" "*" "@types/markdown-it" "*"
"@types/markdown-it@*": "@types/markdown-it@*":
version "10.0.3" version "12.0.0"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-10.0.3.tgz#a9800d14b112c17f1de76ec33eff864a4815eec7" resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.0.0.tgz#b2f421565df814c001d071c398bd09d4777ef34d"
integrity sha512-daHJk22isOUvNssVGF2zDnnSyxHhFYhtjeX4oQaKD6QzL3ZR1QSgiD1g+Q6/WSWYVogNXYDXODtbgW/WiFCtyw== integrity sha512-+RJNprPSIcEUBzj3nx8WYwRsDdAKF6/dG932OleYKbTqBSJ7VvZK0JbPKeEpIYxoniUhgvgyZjO4vlCd4mFTdw==
dependencies: dependencies:
"@types/highlight.js" "^9.7.0" "@types/highlight.js" "^9.7.0"
"@types/linkify-it" "*" "@types/linkify-it" "*"
"@types/mdurl" "*" "@types/mdurl" "*"
highlight.js "^9.7.0"
"@types/mdurl@*": "@types/mdurl@*":
version "1.0.2" version "1.0.2"
...@@ -1812,14 +1807,14 @@ ...@@ -1812,14 +1807,14 @@
form-data "^3.0.0" form-data "^3.0.0"
"@types/node@*": "@types/node@*":
version "14.14.10" version "14.14.14"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.10.tgz#5958a82e41863cfc71f2307b3748e3491ba03785" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.14.tgz#f7fd5f3cc8521301119f63910f0fb965c7d761ae"
integrity sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ== integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==
"@types/node@^10.14.22": "@types/node@^10.14.22":
version "10.17.47" version "10.17.49"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.47.tgz#cc88a242a835789456cfcf374928400d9f4b291c" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.49.tgz#ecf0b67bab4b84d0ec9b0709db4aac3824a51c4a"
integrity sha512-YZ1mMAdUPouBZCdeugjV8y1tqqr28OyL8DYbH5ePCfe9zcXtvbh1wDBy7uzlHkXo3Qi07kpzXfvycvrkby/jXw== integrity sha512-PGaJNs5IZz5XgzwJvL/1zRfZB7iaJ5BydZ8/Picm+lUNYoNO9iVTQkVy5eUh0dZDrx3rBOIs3GCbCRmMuYyqwg==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.0" version "2.4.0"
...@@ -1934,7 +1929,7 @@ ...@@ -1934,7 +1929,7 @@
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45"
integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==
"@types/serve-static@*", "@types/serve-static@^1.13.3": "@types/serve-static@*":
version "1.13.8" version "1.13.8"
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.8.tgz#851129d434433c7082148574ffec263d58309c46" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.8.tgz#851129d434433c7082148574ffec263d58309c46"
integrity sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA== integrity sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA==
...@@ -2003,9 +1998,9 @@ ...@@ -2003,9 +1998,9 @@
integrity sha512-WGZCqBZZ0mXN2RxvLHL6/7RCu+OWs28jgQMP04LWfpyJlQUMTR6YU9CNJAKDgbw+EV/u687INXuLUc7FuML/4g== integrity sha512-WGZCqBZZ0mXN2RxvLHL6/7RCu+OWs28jgQMP04LWfpyJlQUMTR6YU9CNJAKDgbw+EV/u687INXuLUc7FuML/4g==
"@types/webpack-sources@*": "@types/webpack-sources@*":
version "2.0.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.0.0.tgz#08216ab9be2be2e1499beaebc4d469cec81e82a7" resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.1.0.tgz#8882b0bd62d1e0ce62f183d0d01b72e6e82e8c10"
integrity sha512-a5kPx98CNFRKQ+wqawroFunvFqv7GHm/3KOI52NY9xWADgc8smu4R6prt4EU/M4QfVjvgBkMqU4fBhw3QfMVkg== integrity sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/source-list-map" "*" "@types/source-list-map" "*"
...@@ -2047,9 +2042,9 @@ ...@@ -2047,9 +2042,9 @@
integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
"@types/yargs@^15": "@types/yargs@^15":
version "15.0.10" version "15.0.12"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.10.tgz#0fe3c8173a0d5c3e780b389050140c3f5ea6ea74" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.12.tgz#6234ce3e3e3fa32c5db301a170f96a599c960d74"
integrity sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ== integrity sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==
dependencies: dependencies:
"@types/yargs-parser" "*" "@types/yargs-parser" "*"
...@@ -3542,16 +3537,16 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: ...@@ -3542,16 +3537,16 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
caniuse-db "^1.0.30000639" caniuse-db "^1.0.30000639"
electron-to-chromium "^1.2.7" electron-to-chromium "^1.2.7"
browserslist@^4.14.5, browserslist@^4.14.7: browserslist@^4.14.5, browserslist@^4.15.0:
version "4.14.7" version "4.16.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.7.tgz#c071c1b3622c1c2e790799a37bb09473a4351cb6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.0.tgz#410277627500be3cb28a1bfe037586fbedf9488b"
integrity sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ== integrity sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ==
dependencies: dependencies:
caniuse-lite "^1.0.30001157" caniuse-lite "^1.0.30001165"
colorette "^1.2.1" colorette "^1.2.1"
electron-to-chromium "^1.3.591" electron-to-chromium "^1.3.621"
escalade "^3.1.1" escalade "^3.1.1"
node-releases "^1.1.66" node-releases "^1.1.67"
buffer-alloc-unsafe@^1.1.0: buffer-alloc-unsafe@^1.1.0:
version "1.1.0" version "1.1.0"
...@@ -3750,14 +3745,14 @@ caniuse-api@^1.5.2: ...@@ -3750,14 +3745,14 @@ caniuse-api@^1.5.2:
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30001161" version "1.0.30001170"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001161.tgz#69de68582cbd3c57c24034debc4be8c5a4663474" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001170.tgz#3417e94e73536b5bf567e9e9c4b7c1901c408c6a"
integrity sha512-wF8lcUGCKT+Od+27u4z5ahGSI5lB/xSTf/V8sEU5inDsORj0B4zGzs8YVdd76EIjA5muAjhfrkSTclXUb7MDFw== integrity sha512-NzQ5cfHv/pCgVbNWl9eIILms/hb57N+8Ku2yf2IOkBCmYSF4pweMtLTbBAwN/LzKPEtxE42hhTz0sb8gBlkPXA==
caniuse-lite@^1.0.30001157: caniuse-lite@^1.0.30001165:
version "1.0.30001161" version "1.0.30001170"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001161.tgz#64f7ffe79ee780b8c92843ff34feb36cea4651e0" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7"
integrity sha512-JharrCDxOqPLBULF9/SPa6yMcBRTjZARJ6sc3cuKrPfyIk64JN6kuMINWqA99Xc8uElMFcROliwtz0n9pYej+g== integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA==
capture-stack-trace@^1.0.0: capture-stack-trace@^1.0.0:
version "1.0.1" version "1.0.1"
...@@ -3985,11 +3980,12 @@ cli-spinners@^2.0.0: ...@@ -3985,11 +3980,12 @@ cli-spinners@^2.0.0:
integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ== integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==
cli-table@^0.3.1: cli-table@^0.3.1:
version "0.3.1" version "0.3.4"
resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.4.tgz#5b37fd723751f1a6e9e70d55953a75e16eab958e"
integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM= integrity sha512-1vinpnX/ZERcmE443i3SZTmU5DF0rPO9DrL4I2iVAllhxzCM9SzPlHnz19fsZB78htkKZvYBvj6SZ6vXnaxmTA==
dependencies: dependencies:
colors "1.0.3" chalk "^2.4.1"
string-width "^4.2.0"
cli-truncate@^0.2.1: cli-truncate@^0.2.1:
version "0.2.1" version "0.2.1"
...@@ -4160,11 +4156,6 @@ colormin@^1.0.5: ...@@ -4160,11 +4156,6 @@ colormin@^1.0.5:
css-color-names "0.0.4" css-color-names "0.0.4"
has "^1.0.1" has "^1.0.1"
colors@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
colors@^1.1.2, colors@^1.3.3, colors@^1.4.0: colors@^1.1.2, colors@^1.3.3, colors@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
...@@ -4217,16 +4208,6 @@ concat-stream@^1.5.0, concat-stream@^1.6.2: ...@@ -4217,16 +4208,6 @@ concat-stream@^1.5.0, concat-stream@^1.6.2:
readable-stream "^2.2.2" readable-stream "^2.2.2"
typedarray "^0.0.6" typedarray "^0.0.6"
connect@^3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8"
integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==
dependencies:
debug "2.6.9"
finalhandler "1.1.2"
parseurl "~1.3.3"
utils-merge "1.0.1"
console-browserify@^1.1.0: console-browserify@^1.1.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
...@@ -4276,6 +4257,13 @@ cookie@^0.4.0: ...@@ -4276,6 +4257,13 @@ cookie@^0.4.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
copy-anything@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.1.tgz#2afbce6da684bdfcbec93752fa762819cb480d9a"
integrity sha512-lA57e7viQHOdPQcrytv5jFeudZZOXuyk47lZym279FiDQ8jeZomXiGuVf6ffMKkJ+3TIai3J1J3yi6M+/4U35g==
dependencies:
is-what "^3.7.1"
copy-concurrently@^1.0.0: copy-concurrently@^1.0.0:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
...@@ -4307,12 +4295,12 @@ copy-webpack-plugin@^4.5.0: ...@@ -4307,12 +4295,12 @@ copy-webpack-plugin@^4.5.0:
p-limit "^1.0.0" p-limit "^1.0.0"
serialize-javascript "^1.4.0" serialize-javascript "^1.4.0"
core-js-compat@^3.7.0: core-js-compat@^3.8.0:
version "3.8.0" version "3.8.1"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.0.tgz#3248c6826f4006793bd637db608bca6e4cd688b1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.1.tgz#8d1ddd341d660ba6194cbe0ce60f4c794c87a36e"
integrity sha512-o9QKelQSxQMYWHXc/Gc4L8bx/4F7TTraE5rhuN8I7mKBt5dBIUpXpIR3omv70ebr8ST5R3PqbDQr+ZI3+Tt1FQ== integrity sha512-a16TLmy9NVD1rkjUGbwuyWkiDoN0FDpAwrfLONvHFQx0D9k7J9y0srwMT8QP/Z6HE3MIFaVynEeYwZwPX1o5RQ==
dependencies: dependencies:
browserslist "^4.14.7" browserslist "^4.15.0"
semver "7.0.0" semver "7.0.0"
core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0:
...@@ -4826,12 +4814,12 @@ dom-helpers@^5.1.3: ...@@ -4826,12 +4814,12 @@ dom-helpers@^5.1.3:
csstype "^3.0.2" csstype "^3.0.2"
dom-serializer@^1.0.1: dom-serializer@^1.0.1:
version "1.1.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.1.0.tgz#5f7c828f1bfc44887dc2a315ab5c45691d544b58" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1"
integrity sha512-ox7bvGXt2n+uLWtCRLybYx60IrOlWL/aCebWJk1T0d4m3y2tzf4U3ij9wBMUb6YJZpz06HCCYuyCDveE2xXmzQ== integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==
dependencies: dependencies:
domelementtype "^2.0.1" domelementtype "^2.0.1"
domhandler "^3.0.0" domhandler "^4.0.0"
entities "^2.0.0" entities "^2.0.0"
domain-browser@^1.1.1: domain-browser@^1.1.1:
...@@ -4839,31 +4827,38 @@ domain-browser@^1.1.1: ...@@ -4839,31 +4827,38 @@ domain-browser@^1.1.1:
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
domelementtype@^2.0.1: domelementtype@^2.0.1, domelementtype@^2.1.0:
version "2.0.2" version "2.1.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.2.tgz#f3b6e549201e46f588b59463dd77187131fe6971" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e"
integrity sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA== integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==
domhandler@^3.0.0, domhandler@^3.3.0: domhandler@^3.0.0:
version "3.3.0" version "3.3.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a"
integrity sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA== integrity sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==
dependencies: dependencies:
domelementtype "^2.0.1" domelementtype "^2.0.1"
domhandler@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e"
integrity sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==
dependencies:
domelementtype "^2.1.0"
dompurify@^2.0.11: dompurify@^2.0.11:
version "2.2.2" version "2.2.6"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.2.tgz#cb8c2b1a2f3c8a0b565127504ae4eedec176a972" resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.6.tgz#54945dc5c0b45ce5ae228705777e8e59d7b2edc4"
integrity sha512-BsGR4nDLaC5CNBnyT5I+d5pOeaoWvgVeg6Gq/aqmKYWMPR07131u60I80BvExLAJ0FQEIBQ1BTicw+C5+jOyrg== integrity sha512-7b7ZArhhH0SP6W2R9cqK6RjaU82FZ2UPM7RO8qN1b1wyvC/NY1FNWcX1Pu00fFOAnzEORtwXe4bPaClg6pUybQ==
domutils@^2.0.0: domutils@^2.0.0:
version "2.4.2" version "2.4.4"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.2.tgz#7ee5be261944e1ad487d9aa0616720010123922b" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3"
integrity sha512-NKbgaM8ZJOecTZsIzW5gSuplsX2IWW2mIK7xVr8hTQF2v1CJWTmLZ1HOCh5sH+IzVPAGE5IucooOkvwBRAdowA== integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==
dependencies: dependencies:
dom-serializer "^1.0.1" dom-serializer "^1.0.1"
domelementtype "^2.0.1" domelementtype "^2.0.1"
domhandler "^3.3.0" domhandler "^4.0.0"
download-stats@^0.3.4: download-stats@^0.3.4:
version "0.3.4" version "0.3.4"
...@@ -4875,9 +4870,9 @@ download-stats@^0.3.4: ...@@ -4875,9 +4870,9 @@ download-stats@^0.3.4:
moment "^2.15.1" moment "^2.15.1"
drivelist@^9.0.2: drivelist@^9.0.2:
version "9.2.1" version "9.2.2"
resolved "https://registry.yarnpkg.com/drivelist/-/drivelist-9.2.1.tgz#d838ea1f947492b4e70f5d3b815a57571b6212a6" resolved "https://registry.yarnpkg.com/drivelist/-/drivelist-9.2.2.tgz#f62ecd1bf2b931cff6c4ca5bee318950e72914ca"
integrity sha512-oiMDLWUOhoqvVWDvjSrWcz2I42dNuH0Pf1SZlEr86I413n7XoY/YANnqipSynpe86arBW4EbNur7VAl5h8QQ3Q== integrity sha512-kuigQbvkc9+Y6Rf36d9nv4g4PB19UUPOvxRdQE3JEtggCqdxYCPEsNm6WYOudkfdMIFnHtmbS35QowL/hI/sGQ==
dependencies: dependencies:
bindings "^1.3.0" bindings "^1.3.0"
debug "^3.1.0" debug "^3.1.0"
...@@ -4974,10 +4969,10 @@ electron-rebuild@^1.8.6: ...@@ -4974,10 +4969,10 @@ electron-rebuild@^1.8.6:
spawn-rx "^3.0.0" spawn-rx "^3.0.0"
yargs "^14.2.0" yargs "^14.2.0"
electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.591: electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.621:
version "1.3.609" version "1.3.631"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.609.tgz#938735afa300ebf4eaec7e3fff96b7f3d74ac5f0" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.631.tgz#b28ebc7bfb348bb0aede2fae8888d775ddb6f5ee"
integrity sha512-kcmRWmlHsUKKLfsSKSf7VqeTX4takM5ndjVTM3et3qpDCceITYI1DixvIfSDIngALoaTnpoMXD3SXSMpzHkYKA== integrity sha512-mPEG/52142po0XK1jQkZtbMmp38MZtQ3JDFItYxV65WXyhxDYEQ54tP4rb93m0RbMlZqQ+4zBw2N7UumSgGfbA==
elegant-spinner@^1.0.1: elegant-spinner@^1.0.1:
version "1.0.1" version "1.0.1"
...@@ -5059,9 +5054,9 @@ errlop@^2.0.0: ...@@ -5059,9 +5054,9 @@ errlop@^2.0.0:
integrity sha512-e64Qj9+4aZzjzzFpZC7p5kmm/ccCrbLhAJplhsDXQFs87XTsXwOpH4s1Io2s90Tau/8r2j9f4l/thhDevRjzxw== integrity sha512-e64Qj9+4aZzjzzFpZC7p5kmm/ccCrbLhAJplhsDXQFs87XTsXwOpH4s1Io2s90Tau/8r2j9f4l/thhDevRjzxw==
errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: errno@^0.1.1, errno@^0.1.3, errno@~0.1.7:
version "0.1.7" version "0.1.8"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
dependencies: dependencies:
prr "~1.0.1" prr "~1.0.1"
...@@ -5466,10 +5461,10 @@ figures@^3.0.0: ...@@ -5466,10 +5461,10 @@ figures@^3.0.0:
dependencies: dependencies:
escape-string-regexp "^1.0.5" escape-string-regexp "^1.0.5"
file-icons-js@^1.0.3: file-icons-js@~1.0.3:
version "1.1.0" version "1.0.3"
resolved "https://registry.yarnpkg.com/file-icons-js/-/file-icons-js-1.1.0.tgz#da5e0679a58ab661abf9ec6c2a47c5f14f638ab6" resolved "https://registry.yarnpkg.com/file-icons-js/-/file-icons-js-1.0.3.tgz#d0765dc1d86aba4b2d7664a39e4ef7af9f12c5af"
integrity sha512-EwR5RJoNIp5Wnzc+AF1oyBYZhOqPuPm0QHzfCaeh5KJpLB5lWIsxswiAwj3m8lIj7ddBzYBJDDnIr6IVrRCy8Q== integrity sha512-n4zoKEpMaAxBTUB7wtgrFBa4dM3b7mBLLA1VI/Q5Cdk/k2UA8S8oaxvnECp3QOzg0Dn+KKRzfIHF7qSdRkA65Q==
file-loader@^1.1.11: file-loader@^1.1.11:
version "1.1.11" version "1.1.11"
...@@ -5553,7 +5548,7 @@ fill-range@^7.0.1: ...@@ -5553,7 +5548,7 @@ fill-range@^7.0.1:
dependencies: dependencies:
to-regex-range "^5.0.1" to-regex-range "^5.0.1"
finalhandler@1.1.2, finalhandler@~1.1.2: finalhandler@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
...@@ -5651,9 +5646,9 @@ flatten@^1.0.2: ...@@ -5651,9 +5646,9 @@ flatten@^1.0.2:
integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==
flow-parser@^0.*: flow-parser@^0.*:
version "0.138.0" version "0.141.0"
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.138.0.tgz#2d9818f6b804d66f90949dfa8b4892f3a0af546d" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.141.0.tgz#b9e176e54dd204b2375e35df10caf6607c3d09a1"
integrity sha512-LFnTyjrv39UvCWl8NOcpByr/amj8a5k5z7isO2wv4T43nNrUnHQwX3rarTz9zcpHXkDAQv6X4MfQ4ZzJUptpbw== integrity sha512-WKdBiR9sDfkgEyPGhIgldUrVM08D57CgHLgd0FOXbhcVYXNfw+eHSApQ8SdcdQQoqrOvhlcVRB8lsn9bD5GQOw==
flush-write-stream@^1.0.0: flush-write-stream@^1.0.0:
version "1.1.1" version "1.1.1"
...@@ -5861,9 +5856,9 @@ get-func-name@^2.0.0: ...@@ -5861,9 +5856,9 @@ get-func-name@^2.0.0:
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
get-intrinsic@^1.0.0: get-intrinsic@^1.0.0:
version "1.0.1" version "1.0.2"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
integrity sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg== integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
dependencies: dependencies:
function-bind "^1.1.1" function-bind "^1.1.1"
has "^1.0.3" has "^1.0.3"
...@@ -6278,7 +6273,7 @@ he@1.2.0: ...@@ -6278,7 +6273,7 @@ he@1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
highlight.js@^9.12.0, highlight.js@^9.7.0: highlight.js@^9.12.0:
version "9.18.5" version "9.18.5"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825"
integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA== integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==
...@@ -6516,9 +6511,9 @@ inherits@2.0.3: ...@@ -6516,9 +6511,9 @@ inherits@2.0.3:
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@^1.3.4, ini@~1.3.0: ini@^1.3.4, ini@~1.3.0:
version "1.3.5" version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
inquirer@^5.1.0: inquirer@^5.1.0:
version "5.2.0" version "5.2.0"
...@@ -6579,9 +6574,9 @@ invariant@^2.2.2: ...@@ -6579,9 +6574,9 @@ invariant@^2.2.2:
loose-envify "^1.0.0" loose-envify "^1.0.0"
inversify@^5.0.1: inversify@^5.0.1:
version "5.0.1" version "5.0.5"
resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.0.1.tgz#500d709b1434896ce5a0d58915c4a4210e34fb6e" resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.0.5.tgz#bd1f8e6d8e0f739331acd8ba9bc954635aae0bbf"
integrity sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ== integrity sha512-60QsfPz8NAU/GZqXu8hJ+BhNf/C/c+Hp0eDc6XMIJTxBiP36AQyyQKpBkOVTLWBFDQWYVHpbbEuIsHu9dLuJDA==
invert-kv@^2.0.0: invert-kv@^2.0.0:
version "2.0.0" version "2.0.0"
...@@ -6778,9 +6773,9 @@ is-natural-number@^4.0.1: ...@@ -6778,9 +6773,9 @@ is-natural-number@^4.0.1:
integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=
is-negative-zero@^2.0.0: is-negative-zero@^2.0.0:
version "2.0.0" version "2.0.1"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==
is-number@^2.1.0: is-number@^2.1.0:
version "2.1.0" version "2.1.0"
...@@ -6807,9 +6802,9 @@ is-number@^7.0.0: ...@@ -6807,9 +6802,9 @@ is-number@^7.0.0:
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-object@^1.0.1: is-object@^1.0.1:
version "1.0.1" version "1.0.2"
resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf"
integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==
is-observable@^0.2.0: is-observable@^0.2.0:
version "0.2.0" version "0.2.0"
...@@ -6908,6 +6903,11 @@ is-utf8@^0.2.0, is-utf8@^0.2.1: ...@@ -6908,6 +6903,11 @@ is-utf8@^0.2.0, is-utf8@^0.2.1:
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
is-what@^3.7.1:
version "3.12.0"
resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.12.0.tgz#f4405ce4bd6dd420d3ced51a026fb90e03705e55"
integrity sha512-2ilQz5/f/o9V7WRWJQmpFYNmQFZ9iM+OXRonZKcYgTkCzjb949Vi4h282PD1UfmgHk666rcWonbRJ++KI41VGw==
is-windows@^1.0.1, is-windows@^1.0.2: is-windows@^1.0.1, is-windows@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
...@@ -7216,10 +7216,11 @@ less-loader@~2.2.3: ...@@ -7216,10 +7216,11 @@ less-loader@~2.2.3:
loader-utils "^0.2.5" loader-utils "^0.2.5"
less@^3.0.3: less@^3.0.3:
version "3.12.2" version "3.13.1"
resolved "https://registry.yarnpkg.com/less/-/less-3.12.2.tgz#157e6dd32a68869df8859314ad38e70211af3ab4" resolved "https://registry.yarnpkg.com/less/-/less-3.13.1.tgz#0ebc91d2a0e9c0c6735b83d496b0ab0583077909"
integrity sha512-+1V2PCMFkL+OIj2/HrtrvZw0BC0sYLMICJfbQjuj/K8CEnlrFX6R5cKKgzzttsZDHyxQNL1jqMREjKN3ja/E3Q== integrity sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==
dependencies: dependencies:
copy-anything "^2.0.1"
tslib "^1.10.0" tslib "^1.10.0"
optionalDependencies: optionalDependencies:
errno "^0.1.1" errno "^0.1.1"
...@@ -7459,6 +7460,13 @@ lru-cache@^5.1.1: ...@@ -7459,6 +7460,13 @@ lru-cache@^5.1.1:
dependencies: dependencies:
yallist "^3.0.2" yallist "^3.0.2"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
macaddress@^0.2.9: macaddress@^0.2.9:
version "0.2.9" version "0.2.9"
resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.9.tgz#3579b8b9acd5b96b4553abf0f394185a86813cb3" resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.9.tgz#3579b8b9acd5b96b4553abf0f394185a86813cb3"
...@@ -7527,9 +7535,9 @@ markdown-it@^8.4.0: ...@@ -7527,9 +7535,9 @@ markdown-it@^8.4.0:
uc.micro "^1.0.5" uc.micro "^1.0.5"
math-expression-evaluator@^1.2.14: math-expression-evaluator@^1.2.14:
version "1.3.3" version "1.3.7"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.3.3.tgz#8b61badc2aadffb166c3847707057ca955c1684f" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.3.7.tgz#1b62225db86af06f7ea1fd9576a34af605a5b253"
integrity sha512-geKTlqoxnjqHoWqB71h0kchWIC23a3yfwwbZu4E2amjvGLF+fTjCCwBQOHkE0/oHc6KdnSVmMt3QB82KaPmKEA== integrity sha512-nrbaifCl42w37hYd6oRLvoymFK42tWB+WQTMFtksDGQMi5GvlJwnz/CsS30FFAISFLtX+A0csJ0xLiuuyyec7w==
math-random@^1.0.1: math-random@^1.0.1:
version "1.0.4" version "1.0.4"
...@@ -7724,9 +7732,9 @@ mime@1.6.0, mime@^1.4.1: ...@@ -7724,9 +7732,9 @@ mime@1.6.0, mime@^1.4.1:
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
mime@^2.0.3, mime@^2.4.4: mime@^2.0.3, mime@^2.4.4:
version "2.4.6" version "2.4.7"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.7.tgz#962aed9be0ed19c91fd7dc2ece5d7f4e89a90d74"
integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== integrity sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA==
mimic-fn@^1.0.0: mimic-fn@^1.0.0:
version "1.2.0" version "1.2.0"
...@@ -7922,11 +7930,16 @@ ms@2.1.1: ...@@ -7922,11 +7930,16 @@ ms@2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
ms@2.1.2, ms@^2.1.1: ms@2.1.2:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ms@^2.1.1:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
multimatch@^2.0.0: multimatch@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
...@@ -8081,7 +8094,7 @@ node-libs-browser@^2.2.1: ...@@ -8081,7 +8094,7 @@ node-libs-browser@^2.2.1:
util "^0.11.0" util "^0.11.0"
vm-browserify "^1.0.1" vm-browserify "^1.0.1"
node-releases@^1.1.66: node-releases@^1.1.67:
version "1.1.67" version "1.1.67"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12"
integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==
...@@ -8233,9 +8246,9 @@ object-copy@^0.1.0: ...@@ -8233,9 +8246,9 @@ object-copy@^0.1.0:
kind-of "^3.0.3" kind-of "^3.0.3"
object-inspect@^1.8.0: object-inspect@^1.8.0:
version "1.8.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1" version "1.1.1"
...@@ -9404,9 +9417,9 @@ react-perfect-scrollbar@^1.5.3: ...@@ -9404,9 +9417,9 @@ react-perfect-scrollbar@^1.5.3:
prop-types "^15.6.1" prop-types "^15.6.1"
react-virtualized@^9.20.0: react-virtualized@^9.20.0:
version "9.22.2" version "9.22.3"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.2.tgz#217a870bad91e5438f46f01a009e1d8ce1060a5a" resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
integrity sha512-5j4h4FhxTdOpBKtePSs1yk6LDNT4oGtUwjT7Nkh61Z8vv3fTG/XeOf8J4li1AYaexOwTXnw0HFVxsV0GBUqwRw== integrity sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==
dependencies: dependencies:
"@babel/runtime" "^7.7.2" "@babel/runtime" "^7.7.2"
clsx "^1.0.4" clsx "^1.0.4"
...@@ -9794,7 +9807,7 @@ resolve-url@^0.2.1: ...@@ -9794,7 +9807,7 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.8.1: resolve@^1.1.6, resolve@^1.10.0:
version "1.19.0" version "1.19.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c"
integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==
...@@ -9997,9 +10010,11 @@ semver@^6.0.0, semver@^6.3.0: ...@@ -9997,9 +10010,11 @@ semver@^6.0.0, semver@^6.3.0:
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.1.3, semver@^7.2.1: semver@^7.1.3, semver@^7.2.1:
version "7.3.2" version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
dependencies:
lru-cache "^6.0.0"
send@0.17.1: send@0.17.1:
version "0.17.1" version "0.17.1"
...@@ -10032,7 +10047,7 @@ serialize-javascript@^4.0.0: ...@@ -10032,7 +10047,7 @@ serialize-javascript@^4.0.0:
dependencies: dependencies:
randombytes "^2.1.0" randombytes "^2.1.0"
serve-static@1.14.1, serve-static@^1.14.1: serve-static@1.14.1:
version "1.14.1" version "1.14.1"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
...@@ -10307,9 +10322,9 @@ spdx-expression-parse@^3.0.0: ...@@ -10307,9 +10322,9 @@ spdx-expression-parse@^3.0.0:
spdx-license-ids "^3.0.0" spdx-license-ids "^3.0.0"
spdx-license-ids@^3.0.0: spdx-license-ids@^3.0.0:
version "3.0.6" version "3.0.7"
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65"
integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw== integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==
split-string@^3.0.1, split-string@^3.0.2: split-string@^3.0.1, split-string@^3.0.2:
version "3.1.0" version "3.1.0"
...@@ -11195,9 +11210,9 @@ uuid@^3.3.2: ...@@ -11195,9 +11210,9 @@ uuid@^3.3.2:
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.0.0: uuid@^8.0.0:
version "8.3.1" version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache@^1.1.2: v8-compile-cache@^1.1.2:
version "1.1.2" version "1.1.2"
...@@ -11277,16 +11292,16 @@ vm-browserify@^1.0.1: ...@@ -11277,16 +11292,16 @@ vm-browserify@^1.0.1:
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
vscode-debugprotocol@^1.32.0: vscode-debugprotocol@^1.32.0:
version "1.42.0" version "1.43.0"
resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.42.0.tgz#86ad5d95c52a8fd255bc40476414b3a417160f84" resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.43.0.tgz#fe5bcfa7021c250e78c3cf203d392e98b5de268c"
integrity sha512-nVsfVCat9FZlOso5SYB1LQQiFGifTyOALpkpJdudDlRXGTpI3mSFiDYXWaoFm7UcfqTOzn1SC7Hqw4d89btT0w== integrity sha512-pnj+9wVS3yPYz/RXoYSN1tCv+D4139ueaY2WC7V6fUd9QZU8IE5s4r/lZUMJ9gAEGz2km/Iv4qcI7Fdlz5xS9w==
vscode-jsonrpc@^5.0.0, vscode-jsonrpc@^5.0.1: vscode-jsonrpc@^5.0.0, vscode-jsonrpc@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794"
integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A== integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==
vscode-languageserver-protocol@^3.15.3: vscode-languageserver-protocol@~3.15.3:
version "3.15.3" version "3.15.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz#3fa9a0702d742cf7883cb6182a6212fcd0a1d8bb" resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz#3fa9a0702d742cf7883cb6182a6212fcd0a1d8bb"
integrity sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw== integrity sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==
...@@ -11299,11 +11314,16 @@ vscode-languageserver-textdocument@^1.0.1: ...@@ -11299,11 +11314,16 @@ vscode-languageserver-textdocument@^1.0.1:
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f"
integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA== integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==
vscode-languageserver-types@3.15.1, vscode-languageserver-types@^3.15.1: vscode-languageserver-types@3.15.1:
version "3.15.1" version "3.15.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de"
integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ== integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==
vscode-languageserver-types@^3.15.1:
version "3.16.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247"
integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==
vscode-ripgrep@^1.2.4: vscode-ripgrep@^1.2.4:
version "1.11.1" version "1.11.1"
resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.11.1.tgz#9fa3c0a96c2939d5a2389f71218bd1bb6eaa8679" resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.11.1.tgz#9fa3c0a96c2939d5a2389f71218bd1bb6eaa8679"
...@@ -11570,9 +11590,9 @@ ws@^6.1.0: ...@@ -11570,9 +11590,9 @@ ws@^6.1.0:
async-limiter "~1.0.0" async-limiter "~1.0.0"
ws@^7.1.2: ws@^7.1.2:
version "7.4.0" version "7.4.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.0.tgz#a5dd76a24197940d4a8bb9e0e152bb4503764da7" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb"
integrity sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ== integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==
xdg-basedir@^2.0.0: xdg-basedir@^2.0.0:
version "2.0.0" version "2.0.0"
...@@ -11618,9 +11638,9 @@ y18n@^3.2.1: ...@@ -11618,9 +11638,9 @@ y18n@^3.2.1:
integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
y18n@^4.0.0: y18n@^4.0.0:
version "4.0.0" version "4.0.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==
yallist@^2.1.2: yallist@^2.1.2:
version "2.1.2" version "2.1.2"
...@@ -11632,6 +11652,11 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: ...@@ -11632,6 +11652,11 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@13.1.2, yargs-parser@^13.1.2: yargs-parser@13.1.2, yargs-parser@^13.1.2:
version "13.1.2" version "13.1.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
......
...@@ -23,4 +23,4 @@ md5sum = df8768f165036dbe0435bd1678b9deb3 ...@@ -23,4 +23,4 @@ md5sum = df8768f165036dbe0435bd1678b9deb3
[template-insecure-turnserver] [template-insecure-turnserver]
filename = instance-insecure-turnserver.cfg.jinja2.in filename = instance-insecure-turnserver.cfg.jinja2.in
md5sum = 0e0807eef75a1ee6f9aef3a6a566a729 md5sum = e88678b9f322251a201860a13f4db6b8
...@@ -59,13 +59,6 @@ name = turnserver-port-listening.py ...@@ -59,13 +59,6 @@ name = turnserver-port-listening.py
config-hostname = {{ listining_ip }} config-hostname = {{ listining_ip }}
config-port = {{ turn_port }} config-port = {{ turn_port }}
[promise-check-turnserver-tls-port]
<= monitor-promise-base
module = check_port_listening
name = turnserver-tls-port-listening.py
config-hostname = {{ listining_ip }}
config-port = {{ turn_tls_port }}
[publish-connection-information] [publish-connection-information]
<= monitor-publish <= monitor-publish
recipe = slapos.cookbook:publish recipe = slapos.cookbook:publish
...@@ -83,7 +76,6 @@ parts = ...@@ -83,7 +76,6 @@ parts =
{{ part_list | join('\n ') }} {{ part_list | join('\n ') }}
# turn server # turn server
turnserver-wrapper turnserver-wrapper
promise-check-turnserver-tls-port
promise-check-turnserver-port promise-check-turnserver-port
eggs-directory = {{ eggs_directory }} eggs-directory = {{ eggs_directory }}
......
...@@ -30,6 +30,3 @@ output = ${buildout:directory}/instance.cfg ...@@ -30,6 +30,3 @@ output = ${buildout:directory}/instance.cfg
[template-insecure-turnserver] [template-insecure-turnserver]
<= download-base <= download-base
[versions]
slapos.recipe.template = 4.4
...@@ -118,6 +118,7 @@ mobility ...@@ -118,6 +118,7 @@ mobility
no-tlsv1 no-tlsv1
no-tlsv1_1 no-tlsv1_1
no-stdout-log no-stdout-log
simple-log
log-file=%(instance_path)s/var/log/turnserver.log log-file=%(instance_path)s/var/log/turnserver.log
userdb=%(instance_path)s/srv/turndb userdb=%(instance_path)s/srv/turndb
pidfile=%(instance_path)s/var/run/turnserver.pid pidfile=%(instance_path)s/var/run/turnserver.pid
...@@ -173,6 +174,7 @@ mobility ...@@ -173,6 +174,7 @@ mobility
no-tlsv1 no-tlsv1
no-tlsv1_1 no-tlsv1_1
no-stdout-log no-stdout-log
simple-log
log-file=%(instance_path)s/var/log/turnserver.log log-file=%(instance_path)s/var/log/turnserver.log
userdb=%(instance_path)s/srv/turndb userdb=%(instance_path)s/srv/turndb
pidfile=%(instance_path)s/var/run/turnserver.pid pidfile=%(instance_path)s/var/run/turnserver.pid
...@@ -239,7 +241,7 @@ simple-log ...@@ -239,7 +241,7 @@ simple-log
log-file=%(instance_path)s/var/log/turnserver.log log-file=%(instance_path)s/var/log/turnserver.log
pidfile=%(instance_path)s/var/run/turnserver.pid pidfile=%(instance_path)s/var/run/turnserver.pid
verbose verbose
user=nxdturn:%(password)""" % {'instance_path': self.partition_path, 'password': password, 'ipv4': self._ipv4_address} user=nxdturn:%(password)s""" % {'instance_path': self.partition_path, 'password': password, 'ipv4': self._ipv4_address}
with open(os.path.join(self.partition_path, 'etc/turnserver.conf')) as f: with open(os.path.join(self.partition_path, 'etc/turnserver.conf')) as f:
current_config = f.read().strip() current_config = f.read().strip()
......
...@@ -59,6 +59,3 @@ recipe = slapos.recipe.build:download ...@@ -59,6 +59,3 @@ recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/instance-varnish.cfg.in url = ${:_profile_base_location_}/instance-varnish.cfg.in
md5sum = 0ea12a4ad2d2e3d406476e35b8d3e3fb md5sum = 0ea12a4ad2d2e3d406476e35b8d3e3fb
mode = 640 mode = 640
[versions]
slapos.recipe.template = 4.4
...@@ -2,20 +2,8 @@ ...@@ -2,20 +2,8 @@
[buildout] [buildout]
extends = software.cfg extends = software.cfg
# wendelin.core [wendelin.core-repository]
parts -= wendelin.core revision =
parts += wendelin.core-dev
[eggs]
# tell erp5 to use -dev eggs instead of released ones
eggs -= ${wendelin.core:egg}
eggs += ${wendelin.core-dev:egg}
# unpin wendelin.core from versions, so that if there is difference between
# version of wendelin.core-dev and what was pinned, buildout does not fallback
# to installing non-dev egg
[versions] [versions]
wendelin.core =
scikit-learn = 0.20 scikit-learn = 0.20
[buildout] [buildout]
versions = versions versions = versions
extends = extends =
../../component/wendelin.core/buildout.cfg
../../component/msgpack-python/buildout.cfg ../../component/msgpack-python/buildout.cfg
../../component/msgpack-numpy/buildout.cfg ../../component/msgpack-numpy/buildout.cfg
../../component/scipy/buildout.cfg ../../component/scipy/buildout.cfg
...@@ -12,7 +11,6 @@ parts += ...@@ -12,7 +11,6 @@ parts +=
msgpack-python msgpack-python
msgpack-numpy msgpack-numpy
ipython ipython
wendelin.core
jupyter jupyter
jupyter-notebook-initialized-scripts jupyter-notebook-initialized-scripts
...@@ -26,7 +24,6 @@ eggs += ...@@ -26,7 +24,6 @@ eggs +=
${scipy:egg} ${scipy:egg}
${msgpack-python:egg} ${msgpack-python:egg}
${msgpack-numpy:egg} ${msgpack-numpy:egg}
${wendelin.core:egg}
${ipython:egg} ${ipython:egg}
[generic_testrunner_init] [generic_testrunner_init]
...@@ -77,7 +74,6 @@ branch = master ...@@ -77,7 +74,6 @@ branch = master
[versions] [versions]
msgpack-numpy = 0.4.4.3 msgpack-numpy = 0.4.4.3
wendelin.core = 0.13
# Test Suite: Wendelin.UnitTest-Master ran at 2020/12/02 16:45:0.883136 UTC # Test Suite: Wendelin.UnitTest-Master ran at 2020/12/02 16:45:0.883136 UTC
......
...@@ -17,6 +17,3 @@ url = ${:_profile_base_location_}/instance.cfg ...@@ -17,6 +17,3 @@ url = ${:_profile_base_location_}/instance.cfg
md5sum = 98a680fe8fddce5dcee455e65c228fde md5sum = 98a680fe8fddce5dcee455e65c228fde
output = ${buildout:directory}/template.cfg output = ${buildout:directory}/template.cfg
mode = 0644 mode = 0644
[versions]
slapos.recipe.template = 2.4.2
...@@ -41,7 +41,7 @@ Server ...@@ -41,7 +41,7 @@ Server
.. topic:: caucased(prefix, caucased_path, data_dir, netloc, service_auto_approve_count=0, key_len=None, promise=None) .. topic:: caucased(prefix, caucased_path, data_dir, netloc, service_auto_approve_count=0, key_len=None, promise=None)
This macro produces the following sections which you will want to reference sothey get instanciated: This macro produces the following sections which you will want to reference so they get instantiated:
- `<prefix>`: Creates `<caucased>` executable file to start `caucased`, - `<prefix>`: Creates `<caucased>` executable file to start `caucased`,
and `<data_dir>` directory for its data storage needs. and `<data_dir>` directory for its data storage needs.
......
...@@ -78,7 +78,6 @@ WSGIUtils = 0.7.2 ...@@ -78,7 +78,6 @@ WSGIUtils = 0.7.2
WSGIserver = 1.3 WSGIserver = 1.3
python-magic = 0.4.18 python-magic = 0.4.18
rdiff-backup = 1.0.5+SlapOSPatched001 rdiff-backup = 1.0.5+SlapOSPatched001
slapos.recipe.template = 4.4
# Required by: # Required by:
# PasteScript== 3.2.0 # PasteScript== 3.2.0
......
...@@ -11,6 +11,8 @@ extends = ...@@ -11,6 +11,8 @@ extends =
../../component/gzip/buildout.cfg ../../component/gzip/buildout.cfg
../../component/xz-utils/buildout.cfg ../../component/xz-utils/buildout.cfg
../../component/haproxy/buildout.cfg ../../component/haproxy/buildout.cfg
../../component/socat/buildout.cfg
../../component/rsyslogd/buildout.cfg
../../component/findutils/buildout.cfg ../../component/findutils/buildout.cfg
../../component/librsvg/buildout.cfg ../../component/librsvg/buildout.cfg
../../component/imagemagick/buildout.cfg ../../component/imagemagick/buildout.cfg
...@@ -53,8 +55,9 @@ extends = ...@@ -53,8 +55,9 @@ extends =
../../component/zbarlight/buildout.cfg ../../component/zbarlight/buildout.cfg
../../component/pylint/buildout.cfg ../../component/pylint/buildout.cfg
../../component/perl-Image-ExifTool/buildout.cfg ../../component/perl-Image-ExifTool/buildout.cfg
../../component/wendelin.core/buildout.cfg
../../component/jupyter-py2/buildout.cfg
../../stack/caucase/buildout.cfg ../../stack/caucase/buildout.cfg
../../software/jupyter/software.cfg
../../software/neoppod/software-common.cfg ../../software/neoppod/software-common.cfg
# keep neoppod extends last # keep neoppod extends last
...@@ -179,6 +182,8 @@ context = ...@@ -179,6 +182,8 @@ context =
key gzip_location gzip:location key gzip_location gzip:location
key xz_utils_location xz-utils:location key xz_utils_location xz-utils:location
key haproxy_location haproxy:location key haproxy_location haproxy:location
key socat_location socat:location
key rsyslogd_location rsyslogd:location
key instance_common_cfg instance-common:rendered key instance_common_cfg instance-common:rendered
key jsl_location jsl:location key jsl_location jsl:location
key jupyter_enable_default erp5-defaults:jupyter-enable-default key jupyter_enable_default erp5-defaults:jupyter-enable-default
...@@ -208,6 +213,7 @@ context = ...@@ -208,6 +213,7 @@ context =
key template_balancer template-balancer:target key template_balancer template-balancer:target
key template_erp5 template-erp5:target key template_erp5 template-erp5:target
key template_haproxy_cfg template-haproxy-cfg:target key template_haproxy_cfg template-haproxy-cfg:target
key template_rsyslogd_cfg template-rsyslogd-cfg:target
key template_jupyter_cfg instance-jupyter-notebook:rendered key template_jupyter_cfg instance-jupyter-notebook:rendered
key template_kumofs template-kumofs:target key template_kumofs template-kumofs:target
key template_mariadb template-mariadb:target key template_mariadb template-mariadb:target
...@@ -273,6 +279,9 @@ fontconfig-includes = ...@@ -273,6 +279,9 @@ fontconfig-includes =
[template-haproxy-cfg] [template-haproxy-cfg]
<= download-base <= download-base
[template-rsyslogd-cfg]
<= download-base
[erp5-bin] [erp5-bin]
<= erp5 <= erp5
repository = https://lab.nexedi.com/nexedi/erp5-bin.git repository = https://lab.nexedi.com/nexedi/erp5-bin.git
...@@ -373,6 +382,7 @@ initialization = ...@@ -373,6 +382,7 @@ initialization =
<= neoppod <= neoppod
eggs = ${neoppod:eggs} eggs = ${neoppod:eggs}
${caucase-eggs:eggs} ${caucase-eggs:eggs}
${wendelin.core:egg}
${numpy:egg} ${numpy:egg}
${matplotlib:egg} ${matplotlib:egg}
${lxml-python:egg} ${lxml-python:egg}
......
...@@ -70,7 +70,7 @@ md5sum = cc19560b9400cecbd23064d55c501eec ...@@ -70,7 +70,7 @@ md5sum = cc19560b9400cecbd23064d55c501eec
[template] [template]
filename = instance.cfg.in filename = instance.cfg.in
md5sum = 5c5250112b87a3937f939028f9594b85 md5sum = b5ac16fdeed8863e465e955ba6d1e12a
[monitor-template-dummy] [monitor-template-dummy]
filename = dummy.cfg filename = dummy.cfg
...@@ -78,7 +78,7 @@ md5sum = 68b329da9893e34099c7d8ad5cb9c940 ...@@ -78,7 +78,7 @@ md5sum = 68b329da9893e34099c7d8ad5cb9c940
[template-erp5] [template-erp5]
filename = instance-erp5.cfg.in filename = instance-erp5.cfg.in
md5sum = 0920a53b10d3811a5f49930adffb62d8 md5sum = 5ea4bcdf74fb429f254af8e8fb7b38a3
[template-zeo] [template-zeo]
filename = instance-zeo.cfg.in filename = instance-zeo.cfg.in
...@@ -86,12 +86,16 @@ md5sum = 0648e38bd5d3a15bb9f93264932740b9 ...@@ -86,12 +86,16 @@ md5sum = 0648e38bd5d3a15bb9f93264932740b9
[template-zope] [template-zope]
filename = instance-zope.cfg.in filename = instance-zope.cfg.in
md5sum = 2f3ddd328ac1c375e483ecb2ef5ffb57 md5sum = c03f93f95333e6a61b857dcfab7f9c0e
[template-balancer] [template-balancer]
filename = instance-balancer.cfg.in filename = instance-balancer.cfg.in
md5sum = 4ba93d28d93bd066d5d19f4f74fc13d7 md5sum = 4a119083eab1eadbaf44468eb4f3381f
[template-haproxy-cfg] [template-haproxy-cfg]
filename = haproxy.cfg.in filename = haproxy.cfg.in
md5sum = fec6a312e4ef84b02837742992aaf495 md5sum = 8de18a61607bd66341a44b95640d293f
[template-rsyslogd-cfg]
filename = rsyslogd.cfg.in
md5sum = 7030e42b50e03f24e036b7785bd6159f
{# This file configures haproxy to redirect requests from ports to specific urls.
# It provides TLS support for server and optionnaly for client.
#
# All parameters are given through the `parameter_dict` variable, see the
# list entries :
#
# parameter_dict = {
# # Path of the PID file. HAProxy will write its own PID to this file
# # Sending USR2 signal to this pid will cause haproxy to reload
# # its configuration.
# "pidfile": "<file_path>",
#
# # AF_UNIX socket for logs. Syslog must be listening on this socket.
# "log-socket": "<file_path>",
#
# # AF_UNIX socket for statistics and control.
# # Haproxy will listen on this socket.
# "stats-socket": "<file_path>",
#
# # IPv4 to listen on
# # All backends from `backend-dict` will listen on this IP.
# "ipv4": "0.0.0.0",
#
# # IPv6 to listen on
# # All backends from `backend-dict` will listen on this IP.
# "ipv6": "::1",
#
# # Certificate and key in PEM format. All ports will serve TLS using
# # this certificate.
# "cert": "<file_path>",
#
# # CA to verify client certificates in PEM format.
# # If set, client certificates will be verified with these CAs.
# # If not set, client certificates are not verified.
# "ca-cert": "<file_path>",
#
# # An optional CRL in PEM format (the file can contain multiple CRL)
# # This is required if ca-cert is passed.
# "crl": "<file_path>",
#
# # Path to use for HTTP health check on backends from `backend-dict`.
# "server-check-path": "/",
#
# # The mapping of backends, keyed by family name
# "backend-dict": {
# "family-secure": {
# ( 8000, # port int
# 'https', # proto str
# True, # ssl_required bool
# [ # backends
# '10.0.0.10:8001', # netloc str
# 1, # max_connection_count int
# False, # is_web_dav bool
# ],
# ),
# },
# "family-default": {
# ( 8002, # port int
# 'https', # proto str
# False, # ssl_required bool
# [ # backends
# '10.0.0.10:8003', # netloc str
# 1, # max_connection_count int
# False, # is_web_dav bool
# ],
# ),
# },
#
# # The mapping of zope paths.
# # This is a Zope specific feature.
# # `enable_authentication` has same meaning as for `backend-list`.
# "zope-virtualhost-monster-backend-dict": {
# # {(ip, port): ( enable_authentication, {frontend_path: ( internal_url ) }, ) }
# ('[::1]', 8004): (
# True, {
# 'zope-1': 'http://10.0.0.10:8001',
# 'zope-2': 'http://10.0.0.10:8002',
# },
# ),
# },
# }
#
# This sample of `parameter_dict` will make haproxy listening to :
# From to `backend-list`:
# For "family-secure":
# - 0.0.0.0:8000 redirecting internaly to http://10.0.0.10:8001 and
# - [::1]:8000 redirecting internaly to http://10.0.0.10:8001
# only accepting requests from clients providing a verified TLS certificate
# emitted by a CA from `ca-cert` and not revoked in `crl`.
# For "family-default":
# - 0.0.0.0:8002 redirecting internaly to http://10.0.0.10:8003
# - [::1]:8002 redirecting internaly to http://10.0.0.10:8003
# accepting requests from any client.
#
# For both families, X-Forwarded-For header will be stripped unless
# client presents a certificate that can be verified with `ca-cert` and `crl`.
#
# From zope-virtualhost-monster-backend-dict`:
# - [::1]:8004 with some path based rewrite-rules redirecting to:
# * http://10.0.0.10/8001 when path matches /zope-1(.*)
# * http://10.0.0.10/8002 when path matches /zope-2(.*)
# with some VirtualHostMonster rewrite rules so zope writes URLs with
# [::1]:8004 as server name.
# For more details, refer to
# https://docs.zope.org/zope2/zope2book/VirtualHosting.html#using-virtualhostroot-and-virtualhostbase-together
-#}
{% set server_check_path = parameter_dict['server-check-path'] -%} {% set server_check_path = parameter_dict['server-check-path'] -%}
global global
maxconn 4096 maxconn 4096
stats socket {{ parameter_dict['socket-path'] }} level admin master-worker
pidfile {{ parameter_dict['pidfile'] }}
# SSL configuration was generated with mozilla SSL Configuration Generator
# generated 2020-10-28, Mozilla Guideline v5.6, HAProxy 2.1, OpenSSL 1.1.1g, modern configuration
# https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=modern&openssl=1.1.1g&guideline=5.6
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tlsv12 no-tls-tickets
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tlsv12 no-tls-tickets
stats socket {{ parameter_dict['stats-socket'] }} level admin
defaults defaults
mode http mode http
retries 1 retries 1
option redispatch option redispatch
maxconn 2000 maxconn 2000
cookie SERVERID rewrite
balance roundrobin balance roundrobin
stats uri /haproxy stats uri /haproxy
stats realm Global\ statistics stats realm Global\ statistics
# it is useless to have timeout much bigger than the one of apache.
# By default apache use 300s, so we set slightly more in order to timeout connect 10s
# make sure that apache will first stop the connection.
timeout server 305s
# Stop waiting in queue for a zope to become available.
# If no zope can be reached after one minute, consider the request will
# never succeed.
timeout queue 60s timeout queue 60s
# The connection should be immediate on LAN, timeout server 305s
# so we should not set more than 5 seconds, and it could be already too much
timeout connect 5s
# As requested in haproxy doc, make this "at least equal to timeout server".
timeout client 305s timeout client 305s
# Use "option httpclose" to not preserve client & server persistent connections
# while handling every incoming request individually, dispatching them one after option http-server-close
# another to servers, in HTTP close mode. This is really needed when haproxy
# is configured with maxconn to 1, without this option browsers are unable # compress some content types
# to render a page compression algo gzip
option httpclose compression type application/font-woff application/font-woff2 application/hal+json application/javascript application/json application/rss+xml application/wasm application/x-font-opentype application/x-font-ttf application/x-javascript application/xml image/svg+xml text/cache-manifest text/css text/html text/javascript text/plain text/xml
{% for name, (port, backend_list) in sorted(parameter_dict['backend-dict'].iteritems()) -%} log {{ parameter_dict['log-socket'] }} local0 info
listen {{ name }}
bind {{ parameter_dict['ip'] }}:{{ port }} {% set bind_ssl_crt = 'ssl crt ' ~ parameter_dict['cert'] ~ ' alpn h2,http/1.1' %}
{% for name, (port, _, certificate_authentication, backend_list) in sorted(parameter_dict['backend-dict'].iteritems()) -%}
listen family_{{ name }}
{%- if parameter_dict.get('ca-cert') -%}
{%- set ssl_auth = ' ca-file ' ~ parameter_dict['ca-cert'] ~ ' verify' ~ ( ' required' if certificate_authentication else ' optional' ) ~ ' crl-file ' ~ parameter_dict['crl'] %}
{%- else %}
{%- set ssl_auth = '' %}
{%- endif %}
bind {{ parameter_dict['ipv4'] }}:{{ port }} {{ bind_ssl_crt }} {{ ssl_auth }}
bind {{ parameter_dict['ipv6'] }}:{{ port }} {{ bind_ssl_crt }} {{ ssl_auth }}
cookie SERVERID rewrite
http-request set-header X-Balancer-Current-Cookie SERVERID http-request set-header X-Balancer-Current-Cookie SERVERID
# remove X-Forwarded-For unless client presented a verified certificate
acl client_cert_verified ssl_c_used ssl_c_verify 0
http-request del-header X-Forwarded-For unless client_cert_verified
# set Remote-User if client presented a verified certificate
http-request del-header Remote-User
http-request set-header Remote-User %{+Q}[ssl_c_s_dn(cn)] if client_cert_verified
# logs
capture request header Referer len 512
capture request header User-Agent len 512
log-format "%{+Q}o %{-Q}ci - - [%trg] %r %ST %B %{+Q}[capture.req.hdr(0)] %{+Q}[capture.req.hdr(1)] %Tt"
{% set has_webdav = [] -%} {% set has_webdav = [] -%}
{% for address, connection_count, webdav in backend_list -%} {% for address, connection_count, webdav in backend_list -%}
{% if webdav %}{% do has_webdav.append(None) %}{% endif -%} {% if webdav %}{% do has_webdav.append(None) %}{% endif -%}
{% set server_name = name ~ '-' ~ loop.index0 -%} {% set server_name = name ~ '-' ~ loop.index0 %}
server {{ server_name }} {{ address }} cookie {{ server_name }} check inter 3s rise 1 fall 2 maxqueue 5 maxconn {{ connection_count }} server {{ server_name }} {{ address }} cookie {{ server_name }} check inter 3s rise 1 fall 2 maxqueue 5 maxconn {{ connection_count }}
{% endfor -%} {%- endfor -%}
{%- if not has_webdav and server_check_path %} {%- if not has_webdav and server_check_path %}
option httpchk GET {{ server_check_path }} option httpchk GET {{ server_check_path }}
{% endif -%} {%- endif %}
{% endfor %}
{% for (ip, port), (_, backend_dict) in sorted(parameter_dict['zope-virtualhost-monster-backend-dict'].iteritems()) -%}
{% set group_name = 'testrunner_' ~ loop.index0 %}
frontend frontend_{{ group_name }}
bind {{ ip }}:{{ port }} {{ bind_ssl_crt }}
timeout client 8h
# logs
capture request header Referer len 512
capture request header User-Agent len 512
log-format "%{+Q}o %{-Q}ci - - [%trg] %r %ST %B %{+Q}[capture.req.hdr(0)] %{+Q}[capture.req.hdr(1)] %Tt"
{% for name in sorted(backend_dict.keys()) %}
use_backend backend_{{ group_name }}_{{ name }} if { path -m beg /{{ name }} }
{%- endfor %}
{% for name, url in sorted(backend_dict.items()) %}
backend backend_{{ group_name }}_{{ name }}
http-request replace-path ^/{{ name }}(.*) /VirtualHostBase/https/{{ ip }}:{{ port }}/VirtualHostRoot/_vh_{{ name }}\1
timeout server 8h
server {{ name }} {{ urlparse.urlparse(url).netloc }}
{%- endfor %}
{% endfor %} {% endfor %}
...@@ -8,10 +8,8 @@ XXX: This template only supports exactly one IPv4 and (if ipv6 is used) one IPv6 ...@@ -8,10 +8,8 @@ XXX: This template only supports exactly one IPv4 and (if ipv6 is used) one IPv6
per partition. No more (undefined result), no less (IndexError). per partition. No more (undefined result), no less (IndexError).
-#} -#}
{% set ipv4 = (ipv4_set | list)[0] -%} {% set ipv4 = (ipv4_set | list)[0] -%}
{% set apache_ip_list = [ipv4] -%}
{% if ipv6_set -%} {% if ipv6_set -%}
{% set ipv6 = (ipv6_set | list)[0] -%} {% set ipv6 = (ipv6_set | list)[0] -%}
{% do apache_ip_list.append('[' ~ ipv6 ~ ']') -%}
{% endif -%} {% endif -%}
[jinja2-template-base] [jinja2-template-base]
...@@ -28,7 +26,7 @@ mode = 644 ...@@ -28,7 +26,7 @@ mode = 644
ca_path='${directory:srv}/caucase-updater/ca.crt', ca_path='${directory:srv}/caucase-updater/ca.crt',
crl_path='${directory:srv}/caucase-updater/crl.pem', crl_path='${directory:srv}/caucase-updater/crl.pem',
key_path='${apache-conf-ssl:caucase-key}', key_path='${apache-conf-ssl:caucase-key}',
on_renew='${apache-graceful:output}', on_renew='${haproxy-reload:output}',
max_sleep=ssl_parameter_dict.get('max-crl-update-delay', 1.0), max_sleep=ssl_parameter_dict.get('max-crl-update-delay', 1.0),
template_csr_pem=ssl_parameter_dict.get('csr'), template_csr_pem=ssl_parameter_dict.get('csr'),
openssl=parameter_dict['openssl'] ~ '/bin/openssl', openssl=parameter_dict['openssl'] ~ '/bin/openssl',
...@@ -42,7 +40,7 @@ mode = 644 ...@@ -42,7 +40,7 @@ mode = 644
{% for frontend_caucase_url in frontend_caucase_url_list -%} {% for frontend_caucase_url in frontend_caucase_url_list -%}
{% set hash = hashlib.md5(frontend_caucase_url).hexdigest() -%} {% set hash = hashlib.md5(frontend_caucase_url).hexdigest() -%}
{% do frontend_caucase_url_hash_list.append(hash) -%} {% do frontend_caucase_url_hash_list.append(hash) -%}
{% set data_dir = '${directory:srv}/client-cert-ca/%s' % hash -%} {% set data_dir = '${directory:client-cert-ca}/%s' % hash -%}
{{ caucase.updater( {{ caucase.updater(
prefix='caucase-updater-%s' % hash, prefix='caucase-updater-%s' % hash,
buildout_bin_directory=parameter_dict['bin-directory'], buildout_bin_directory=parameter_dict['bin-directory'],
...@@ -51,7 +49,7 @@ mode = 644 ...@@ -51,7 +49,7 @@ mode = 644
data_dir=data_dir, data_dir=data_dir,
ca_path='%s/ca.crt' % data_dir, ca_path='%s/ca.crt' % data_dir,
crl_path='%s/crl.pem' % data_dir, crl_path='%s/crl.pem' % data_dir,
on_renew='${caucase-updater-housekeeper:output}; ${apache-graceful:output}', on_renew='${caucase-updater-housekeeper:output}',
max_sleep=ssl_parameter_dict.get('max-crl-update-delay', 1.0), max_sleep=ssl_parameter_dict.get('max-crl-update-delay', 1.0),
openssl=parameter_dict['openssl'] ~ '/bin/openssl', openssl=parameter_dict['openssl'] ~ '/bin/openssl',
)}} )}}
...@@ -71,24 +69,47 @@ input = ...@@ -71,24 +69,47 @@ input =
import subprocess import subprocess
hash_list = {{ repr(frontend_caucase_url_hash_list) }} hash_list = {{ repr(frontend_caucase_url_hash_list) }}
crt_list = ['%s.crt' % e for e in hash_list] crt_list = ['%s.crt' % e for e in hash_list]
crl_list = ['%s.crl' % e for e in hash_list] for path in glob.glob('${haproxy-conf-ssl:ca-cert-dir}/*.crt'):
for path in glob.glob('${apache-conf-ssl:ca-cert-dir}/*.crt'):
if os.path.basename(path) not in crt_list: if os.path.basename(path) not in crt_list:
os.unlink(path) os.unlink(path)
for path in glob.glob('${apache-conf-ssl:crl-dir}/*.crl'): crl_list = ['%s.crl' % e for e in hash_list]
for path in glob.glob('${haproxy-conf-ssl:crl-dir}/*.crl'):
if os.path.basename(path) not in crl_list: if os.path.basename(path) not in crl_list:
os.unlink(path) os.unlink(path)
for hash in hash_list: for hash in hash_list:
crt = '${directory:srv}/client-cert-ca/%s/ca.crt' % hash crt = '${directory:client-cert-ca}/%s/ca.crt' % hash
crt_link = '${apache-conf-ssl:ca-cert-dir}/%s.crt' % hash crt_link = '${haproxy-conf-ssl:ca-cert-dir}/%s.crt' % hash
crl = '${directory:srv}/client-cert-ca/%s/crl.pem' % hash crl = '${directory:client-cert-ca}/%s/crl.pem' % hash
crl_link = '${apache-conf-ssl:crl-dir}/%s.crl' % hash crl_link = '${haproxy-conf-ssl:crl-dir}/%s.crl' % hash
if os.path.isfile(crt) and not os.path.islink(crt_link): if os.path.isfile(crt) and not os.path.islink(crt_link):
os.symlink(crt, crt_link) os.symlink(crt, crt_link)
if os.path.isfile(crl) and not os.path.islink(crl_link): if os.path.isfile(crl) and not os.path.islink(crl_link):
os.symlink(crl, crl_link) os.symlink(crl, crl_link)
subprocess.check_call(['{{ parameter_dict["openssl"] }}/bin/c_rehash', '${apache-conf-ssl:ca-cert-dir}']) subprocess.check_call(['{{ parameter_dict["openssl"] }}/bin/c_rehash', '${haproxy-conf-ssl:ca-cert-dir}'])
subprocess.check_call(['{{ parameter_dict["openssl"] }}/bin/c_rehash', '${apache-conf-ssl:crl-dir}']) subprocess.check_call(['{{ parameter_dict["openssl"] }}/bin/c_rehash', '${haproxy-conf-ssl:crl-dir}'])
# assemble all CA and all CRLs in one file for haproxy
with open('${haproxy-conf-ssl:ca-cert}.tmp', 'w') as f:
for path in glob.glob('${haproxy-conf-ssl:ca-cert-dir}/*.crt'):
with open(path) as in_f:
f.write('#{}\n'.format(path))
f.write(in_f.read() + '\n')
with open('${haproxy-conf-ssl:crl}.tmp', 'w') as f:
for path in glob.glob('${haproxy-conf-ssl:crl-dir}/*.crl'):
with open(path) as in_f:
f.write('#{}\n'.format(path))
f.write(in_f.read() + '\n')
if os.path.exists('${haproxy-conf-ssl:ca-cert}'):
os.unlink('${haproxy-conf-ssl:ca-cert}')
if os.path.exists('${haproxy-conf-ssl:crl}'):
os.unlink('${haproxy-conf-ssl:crl}')
os.rename('${haproxy-conf-ssl:ca-cert}.tmp', '${haproxy-conf-ssl:ca-cert}')
os.rename('${haproxy-conf-ssl:crl}.tmp', '${haproxy-conf-ssl:crl}')
subprocess.check_call(['${haproxy-reload:output}'])
[caucase-updater-housekeeper-run] [caucase-updater-housekeeper-run]
recipe = plone.recipe.command recipe = plone.recipe.command
...@@ -97,9 +118,8 @@ update-command = ${:command} ...@@ -97,9 +118,8 @@ update-command = ${:command}
{% endif -%} {% endif -%}
{% set haproxy_dict = {} -%} {% set haproxy_dict = {} -%}
{% set apache_dict = {} -%}
{% set zope_virtualhost_monster_backend_dict = {} %} {% set zope_virtualhost_monster_backend_dict = {} %}
{% set test_runner_url_dict = {} %} {# family_name => list of apache URLs #} {% set test_runner_url_dict = {} %} {# family_name => list of URLs #}
{% set next_port = itertools.count(slapparameter_dict['tcpv4-port']).next -%} {% set next_port = itertools.count(slapparameter_dict['tcpv4-port']).next -%}
{% for family_name, parameter_id_list in sorted( {% for family_name, parameter_id_list in sorted(
slapparameter_dict['zope-family-dict'].iteritems()) -%} slapparameter_dict['zope-family-dict'].iteritems()) -%}
...@@ -120,19 +140,19 @@ update-command = ${:command} ...@@ -120,19 +140,19 @@ update-command = ${:command}
{% set test_runner_address_list = slapparameter_dict.get(parameter_id ~ '-test-runner-address-list', []) %} {% set test_runner_address_list = slapparameter_dict.get(parameter_id ~ '-test-runner-address-list', []) %}
{% if test_runner_address_list -%} {% if test_runner_address_list -%}
{% set test_runner_backend_mapping = {} %} {% set test_runner_backend_mapping = {} %}
{% set test_runner_apache_url_list = [] %} {% set test_runner_balancer_url_list = [] %}
{% set test_runner_external_port = next_port() %} {% set test_runner_external_port = next_port() %}
{% for i, (test_runner_internal_ip, test_runner_internal_port) in enumerate(test_runner_address_list) %} {% for i, (test_runner_internal_ip, test_runner_internal_port) in enumerate(test_runner_address_list) %}
{% do test_runner_backend_mapping.__setitem__( {% do test_runner_backend_mapping.__setitem__(
'unit_test_' ~ i, 'unit_test_' ~ i,
'http://' ~ test_runner_internal_ip ~ ':' ~ test_runner_internal_port ) %} 'http://' ~ test_runner_internal_ip ~ ':' ~ test_runner_internal_port ) %}
{% do test_runner_apache_url_list.append( {% do test_runner_balancer_url_list.append(
'https://' ~ ipv4 ~ ':' ~ test_runner_external_port ~ '/unit_test_' ~ i ~ '/' ) %} 'https://' ~ ipv4 ~ ':' ~ test_runner_external_port ~ '/unit_test_' ~ i ~ '/' ) %}
{% endfor %} {% endfor %}
{% do zope_virtualhost_monster_backend_dict.__setitem__( {% do zope_virtualhost_monster_backend_dict.__setitem__(
(ipv4, test_runner_external_port), (ipv4, test_runner_external_port),
( ssl_authentication, test_runner_backend_mapping ) ) -%} ( ssl_authentication, test_runner_backend_mapping ) ) -%}
{% do test_runner_url_dict.__setitem__(family_name, test_runner_apache_url_list) -%} {% do test_runner_url_dict.__setitem__(family_name, test_runner_balancer_url_list) -%}
{% endif -%} {% endif -%}
{% endfor -%} {% endfor -%}
...@@ -143,50 +163,69 @@ update-command = ${:command} ...@@ -143,50 +163,69 @@ update-command = ${:command}
# do a no-op getitem. # do a no-op getitem.
-#} -#}
{% do zope_family_address_list[0][0] -%} {% do zope_family_address_list[0][0] -%}
{#
# We use to have haproxy then apache, now haproxy is playing apache's role
# To keep port stable, we consume one port so that haproxy use the same port
# that apache was using before.
-#}
{% set _ = next_port() -%}
{% set haproxy_port = next_port() -%} {% set haproxy_port = next_port() -%}
{% set backend_path = slapparameter_dict['backend-path-dict'][family_name] -%} {% set backend_path = slapparameter_dict['backend-path-dict'][family_name] -%}
{% do haproxy_dict.__setitem__(family_name, (haproxy_port, zope_family_address_list)) -%}
{% if has_webdav -%} {% if has_webdav -%}
{% set internal_scheme = 'http' -%}{# mod_rewrite does not recognise webdav scheme -#}
{% set external_scheme = 'webdavs' -%} {% set external_scheme = 'webdavs' -%}
{% else %} {% else %}
{% set internal_scheme = 'http' -%}
{% set external_scheme = 'https' -%} {% set external_scheme = 'https' -%}
{% endif -%} {% endif -%}
{% do apache_dict.__setitem__(family_name, (next_port(), external_scheme, internal_scheme ~ '://' ~ ipv4 ~ ':' ~ haproxy_port ~ backend_path, slapparameter_dict['ssl-authentication-dict'].get(family_name, False))) -%} {% do haproxy_dict.__setitem__(family_name, (haproxy_port, external_scheme, slapparameter_dict['ssl-authentication-dict'].get(family_name, False), zope_family_address_list)) -%}
{% endfor -%} {% endfor -%}
[haproxy-cfg-parameter-dict] [haproxy-cfg-parameter-dict]
socket-path = ${directory:run}/haproxy.sock ipv4 = {{ ipv4 }}
ipv6 = {{ ipv6 }}
cert = ${haproxy-conf-ssl:certificate}
{% if frontend_caucase_url_list -%}
ca-cert = ${haproxy-conf-ssl:ca-cert}
crl = ${haproxy-conf-ssl:crl}
{% endif %}
stats-socket = ${directory:run}/haproxy.sock
pidfile = ${directory:run}/haproxy.pid
log-socket = ${rsyslogd-cfg-parameter-dict:log-socket}
server-check-path = {{ dumps(slapparameter_dict['haproxy-server-check-path']) }} server-check-path = {{ dumps(slapparameter_dict['haproxy-server-check-path']) }}
backend-dict = {{ dumps(haproxy_dict) }} backend-dict = {{ dumps(haproxy_dict) }}
ip = {{ ipv4 }} zope-virtualhost-monster-backend-dict = {{ dumps(zope_virtualhost_monster_backend_dict) }}
[haproxy-cfg] [haproxy-cfg]
< = jinja2-template-base < = jinja2-template-base
template = {{ parameter_dict['template-haproxy-cfg'] }} template = {{ parameter_dict['template-haproxy-cfg'] }}
rendered = ${directory:etc}/haproxy.cfg rendered = ${directory:etc}/haproxy.cfg
context = section parameter_dict haproxy-cfg-parameter-dict context =
section parameter_dict haproxy-cfg-parameter-dict
import urlparse urlparse
extensions = jinja2.ext.do extensions = jinja2.ext.do
[haproxy-reload]
recipe = collective.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
mode = 700
input =
inline:
#!/bin/sh
kill -USR2 $(cat "${haproxy-cfg-parameter-dict:pidfile}")
[{{ section('haproxy') }}] [{{ section('haproxy') }}]
recipe = slapos.cookbook:wrapper recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:services}/haproxy wrapper-path = ${directory:services-on-watch}/haproxy
command-line = "{{ parameter_dict['haproxy'] }}/sbin/haproxy" -f "${haproxy-cfg:rendered}" command-line = "{{ parameter_dict['haproxy'] }}/sbin/haproxy" -f "${haproxy-cfg:rendered}"
hash-files = ${haproxy-cfg:rendered} hash-files = ${haproxy-cfg:rendered}
[apache-conf-ssl] [apache-conf-ssl]
cert = ${directory:apache-conf}/apache.crt
key = ${directory:apache-conf}/apache.pem
# XXX caucase is/was buggy and this certificate does not match key for instances # XXX caucase is/was buggy and this certificate does not match key for instances
# that were updated, so don't use it yet. # that were updated, so don't use it yet.
caucase-cert = ${directory:apache-conf}/apache-caucase.crt caucase-cert = ${directory:apache-conf}/apache-caucase.crt
caucase-key = ${directory:apache-conf}/apache-caucase.pem caucase-key = ${directory:apache-conf}/apache-caucase.pem
{% if frontend_caucase_url_list -%}
depends = ${caucase-updater-housekeeper-run:recipe}
ca-cert-dir = ${directory:apache-ca-cert-dir}
crl-dir = ${directory:apache-crl-dir}
{%- endif %}
[simplefile] [simplefile]
< = jinja2-template-base < = jinja2-template-base
...@@ -204,95 +243,89 @@ context = key content {{content_section_name}}:content ...@@ -204,95 +243,89 @@ context = key content {{content_section_name}}:content
mode = {{ mode }} mode = {{ mode }}
{%- endmacro %} {%- endmacro %}
[apache-ssl] [{{ section('haproxy-socat-stats')}}]
{% if ssl_parameter_dict.get('key') -%} recipe = slapos.cookbook:wrapper
key = ${apache-ssl-key:rendered} wrapper-path = ${directory:bin}/${:_buildout_section_name_}
cert = ${apache-ssl-cert:rendered} command-line = "{{ parameter_dict['socat'] }}/bin/socat" unix-connect:${haproxy-cfg-parameter-dict:stats-socket} stdio
{{ simplefile('apache-ssl-key', '${apache-conf-ssl:key}', ssl_parameter_dict['key']) }}
{{ simplefile('apache-ssl-cert', '${apache-conf-ssl:cert}', ssl_parameter_dict['cert']) }} [rsyslogd-cfg-parameter-dict]
{% else %} log-socket = ${directory:run}/log.sock
recipe = plone.recipe.command access-log-file = ${directory:log}/apache-access.log
command = "{{ parameter_dict['openssl'] }}/bin/openssl" req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout "${:key}" -out "${:cert}" error-log-file = ${directory:log}/apache-error.log
key = ${apache-conf-ssl:key} pid-file = ${directory:run}/rsyslogd.pid
cert = ${apache-conf-ssl:cert} spool-directory = ${directory:rsyslogd-spool}
{%- endif %}
[rsyslogd-cfg]
<= jinja2-template-base
template = {{ parameter_dict['template-rsyslogd-cfg'] }}
rendered = ${directory:etc}/rsyslogd.conf
context = section parameter_dict rsyslogd-cfg-parameter-dict
[{{ section ('rsyslogd') }}]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['rsyslogd'] }}/sbin/rsyslogd -i ${rsyslogd-cfg-parameter-dict:pid-file} -n -f ${rsyslogd-cfg:rendered}
wrapper-path = ${directory:services-on-watch}/rsyslogd
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
hash-files = ${rsyslogd-cfg:rendered}
[apache-conf-parameter-dict] [{{ section ('rsyslogd-listen-promise') }}]
backend-list = {{ dumps(apache_dict.values()) }} <= monitor-promise-base
zope-virtualhost-monster-backend-dict = {{ dumps(zope_virtualhost_monster_backend_dict) }} module = check_command_execute
ip-list = {{ dumps(apache_ip_list) }} name = rsyslogd_listen_promise.py
pid-file = ${directory:run}/apache.pid config-command = test -S ${rsyslogd-cfg-parameter-dict:log-socket}
log-dir = ${directory:log}
error-log = ${directory:log}/apache-error.log
access-log = ${directory:log}/apache-access.log
# Apache 2.4's default value (60 seconds) can be a bit too short
timeout = 300
# Basic SSL server configuration
cert = ${apache-ssl:cert}
key = ${apache-ssl:key}
cipher =
ssl-session-cache = ${directory:log}/apache-ssl-session-cache
{% if frontend_caucase_url_list -%}
# Client x509 auth
ca-cert-dir = ${apache-conf-ssl:ca-cert-dir}
crl-dir = ${apache-conf-ssl:crl-dir}
{%- endif %}
[apache-conf]
< = jinja2-template-base
template = {{ parameter_dict['template-apache-conf'] }}
rendered = ${directory:apache-conf}/apache.conf
context = section parameter_dict apache-conf-parameter-dict
[{{ section('apache') }}] [haproxy-conf-ssl]
recipe = slapos.cookbook:wrapper certificate = ${build-certificate-and-key:certificate-and-key}
wrapper-path = ${directory:services}/apache {% if frontend_caucase_url_list -%}
command-line = "{{ parameter_dict['apache'] }}/bin/httpd" -f "${apache-conf:rendered}" -DFOREGROUND ca-cert = ${directory:etc}/frontend-ca.pem
wait-for-files = ca-cert-dir = ${directory:ca-cert}
${apache-conf-ssl:cert} crl = ${directory:etc}/frontend-crl.pem
${apache-conf-ssl:key} crl-dir = ${directory:crl}
depends = ${caucase-updater-housekeeper-run:recipe}
{%- endif %}
[apache-graceful] [build-certificate-and-key]
recipe = collective.recipe.template {% if ssl_parameter_dict.get('key') -%}
output = ${directory:bin}/apache-httpd-graceful certificate-and-key = ${tls-certificate-and-key-from-parameters:rendered}
mode = 700 {{ simplefile(
input = inline: 'tls-certificate-and-key-from-parameters',
#!/bin/sh '${directory:etc}/certificate-and-key-from-parameters.pem',
kill -USR1 "$(cat '${apache-conf-parameter-dict:pid-file}')" ssl_parameter_dict['cert'] ~ "\n" ~ ssl_parameter_dict['key']) }}
{% else %}
recipe = plone.recipe.command
command = "{{ parameter_dict['openssl'] }}/bin/openssl" req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout "${:certificate-and-key}" -out "${:certificate-and-key}"
certificate-and-key = ${directory:etc}/certificate-and-key-generated.pem
{%- endif %}
[{{ section('apache-promise') }}] [{{ section('haproxy-promise') }}]
<= monitor-promise-base <= monitor-promise-base
# Check any apache port in ipv4, expect other ports and ipv6 to behave consistently # Check any haproxy port in ipv4, expect other ports and ipv6 to behave consistently
module = check_port_listening module = check_port_listening
name = apache.py name = haproxy.py
config-hostname = {{ ipv4 }} config-hostname = {{ ipv4 }}
config-port = {{ apache_dict.values()[0][0] }} config-port = {{ haproxy_dict.values()[0][0] }}
[{{ section('publish') }}] [{{ section('publish') }}]
recipe = slapos.cookbook:publish.serialised recipe = slapos.cookbook:publish.serialised
{% for family_name, (apache_port, scheme, _, _) in apache_dict.items() -%} {% for family_name, (port, scheme, _, _) in haproxy_dict.items() -%}
{{ family_name ~ '-v6' }} = {% if ipv6_set %}{{ scheme ~ '://[' ~ ipv6 ~ ']:' ~ apache_port }}{% endif %} {{ family_name ~ '-v6' }} = {% if ipv6_set %}{{ scheme ~ '://[' ~ ipv6 ~ ']:' ~ port }}{% endif %}
{{ family_name }} = {{ scheme ~ '://' ~ ipv4 ~ ':' ~ apache_port }} {{ family_name }} = {{ scheme ~ '://' ~ ipv4 ~ ':' ~ port }}
{% endfor -%} {% endfor -%}
{% for family_name, test_runner_url_list in test_runner_url_dict.items() -%} {% for family_name, test_runner_url_list in test_runner_url_dict.items() -%}
{{ family_name ~ '-test-runner-url-list' }} = {{ dumps(test_runner_url_list) }} {{ family_name ~ '-test-runner-url-list' }} = {{ dumps(test_runner_url_list) }}
{% endfor -%} {% endfor -%}
monitor-base-url = ${monitor-publish-parameters:monitor-base-url} monitor-base-url = ${monitor-publish-parameters:monitor-base-url}
[{{ section('logrotate-apache') }}] [{{ section('logrotate-rsyslogd') }}]
< = logrotate-entry-base < = logrotate-entry-base
name = apache name = rsyslogd
log = ${apache-conf-parameter-dict:error-log} ${apache-conf-parameter-dict:access-log} log = ${rsyslogd-cfg-parameter-dict:access-log-file} ${rsyslogd-cfg-parameter-dict:error-log-file}
post = test ! -s ${apache-conf-parameter-dict:pid-file} || {{ parameter_dict['bin-directory'] }}/slapos-kill --pidfile ${apache-conf-parameter-dict:pid-file} -s USR1 post = test ! -s ${rsyslogd-cfg-parameter-dict:pid-file} || kill -HUP $(cat ${rsyslogd-cfg-parameter-dict:pid-file})
[directory] [directory]
recipe = slapos.cookbook:mkdirectory recipe = slapos.cookbook:mkdirectory
apache-conf = ${:etc}/apache
{% if frontend_caucase_url_list -%}
apache-ca-cert-dir = ${:apache-conf}/ssl.crt
apache-crl-dir = ${:apache-conf}/ssl.crl
{% endif -%}
bin = ${buildout:directory}/bin bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc etc = ${buildout:directory}/etc
services = ${:etc}/run services = ${:etc}/run
...@@ -302,6 +335,12 @@ run = ${:var}/run ...@@ -302,6 +335,12 @@ run = ${:var}/run
log = ${:var}/log log = ${:var}/log
srv = ${buildout:directory}/srv srv = ${buildout:directory}/srv
apachedex = ${monitor-directory:private}/apachedex apachedex = ${monitor-directory:private}/apachedex
rsyslogd-spool = ${:run}/rsyslogd-spool
{% if frontend_caucase_url_list -%}
ca-cert = ${:etc}/ssl.crt
crl = ${:etc}/ssl.crl
client-cert-ca = ${:srv}/client-cert-ca
{% endif -%}
[{{ section('resiliency-exclude-file') }}] [{{ section('resiliency-exclude-file') }}]
# Generate rdiff exclude file in case of resiliency # Generate rdiff exclude file in case of resiliency
...@@ -325,9 +364,7 @@ command-line = "{{ parameter_dict['run-apachedex-location'] }}" "{{ parameter_di ...@@ -325,9 +364,7 @@ command-line = "{{ parameter_dict['run-apachedex-location'] }}" "{{ parameter_di
command = generate-apachedex-report command = generate-apachedex-report
[apachedex-parameters] [apachedex-parameters]
# XXX - Sample log file with curent date: apache_access.log-%(date)s.gz apache-log-list = ${rsyslogd-cfg-parameter-dict:access-log-file}
# which will be equivalent to apache_access.log-20150112.gz if the date is 2015-01-12
apache-log-list = ${apache-conf-parameter-dict:access-log}
configuration = {{ slapparameter_dict['apachedex-configuration'] }} configuration = {{ slapparameter_dict['apachedex-configuration'] }}
promise-threshold = {{ slapparameter_dict['apachedex-promise-threshold'] }} promise-threshold = {{ slapparameter_dict['apachedex-promise-threshold'] }}
......
...@@ -173,6 +173,7 @@ return = ...@@ -173,6 +173,7 @@ return =
zope-address-list zope-address-list
hosts-dict hosts-dict
monitor-base-url monitor-base-url
software-release-url
{%- if test_runner_enabled %} {%- if test_runner_enabled %}
test-runner-address-list test-runner-address-list
{% endif %} {% endif %}
...@@ -234,6 +235,7 @@ software-type = zope ...@@ -234,6 +235,7 @@ software-type = zope
{% for custom_name, zope_parameter_dict in zope_partition_dict.items() -%} {% for custom_name, zope_parameter_dict in zope_partition_dict.items() -%}
{% set partition_name = 'zope-' ~ custom_name -%} {% set partition_name = 'zope-' ~ custom_name -%}
{% set section_name = 'request-' ~ partition_name -%} {% set section_name = 'request-' ~ partition_name -%}
{% set promise_software_url_section_name = 'promise-software-url' ~ partition_name -%}
{% set zope_family = zope_parameter_dict.get('family', 'default') -%} {% set zope_family = zope_parameter_dict.get('family', 'default') -%}
{% do zope_family_name_list.append(zope_family) %} {% do zope_family_name_list.append(zope_family) %}
{% set backend_path = zope_parameter_dict.get('backend-path', '') % {'site-id': site_id} %} {% set backend_path = zope_parameter_dict.get('backend-path', '') % {'site-id': site_id} %}
...@@ -262,6 +264,18 @@ config-port-base = {{ dumps(zope_parameter_dict.get('port-base', 2200)) }} ...@@ -262,6 +264,18 @@ config-port-base = {{ dumps(zope_parameter_dict.get('port-base', 2200)) }}
config-webdav = {{ dumps(zope_parameter_dict.get('webdav', False)) }} config-webdav = {{ dumps(zope_parameter_dict.get('webdav', False)) }}
{% if test_runner_enabled -%} {% if test_runner_enabled -%}
config-test-runner-apache-url-list = ${publish-early:{{ zope_family }}-test-runner-url-list} config-test-runner-apache-url-list = ${publish-early:{{ zope_family }}-test-runner-url-list}
[{{ promise_software_url_section_name }}]
# Promise to wait for zope partition to use the expected software URL,
# used on upgrades.
recipe = slapos.cookbook:check_parameter
value = {{ '${' ~ section_name ~ ':connection-software-release-url}' }}
expected-not-value =
expected-value = ${slap-connection:software-release-url}
path = ${directory:bin}/${:_buildout_section_name_}
{% do root_common.section(promise_software_url_section_name) -%}
{% endif -%} {% endif -%}
{% endfor -%} {% endfor -%}
......
...@@ -172,12 +172,20 @@ template = inline: {{ ' ...@@ -172,12 +172,20 @@ template = inline: {{ '
rendered = ${directory:etc}/hosts rendered = ${directory:etc}/hosts
context = key host_dict hosts-parameter:host-dict context = key host_dict hosts-parameter:host-dict
[userhosts-bin]
recipe = slapos.recipe.template:jinja2
mode = 755
template = inline:#!{{ parameter_dict['dash'] }}/bin/dash
export HOSTS=${hosts:rendered}
export LD_PRELOAD={{ parameter_dict['userhosts'] }}:$LD_PRELOAD
exec "$@"
rendered = ${directory:bin}/userhosts
[userhosts-wrapper-base] [userhosts-wrapper-base]
recipe = slapos.cookbook:wrapper recipe = slapos.cookbook:wrapper
environment = environment =
HOSTALIASES=${hostaliases:rendered} HOSTALIASES=${hostaliases:rendered}
HOSTS=${hosts:rendered} command-line = '${userhosts-bin:rendered}' ${:wrapped-command-line}
command-line = '{{ parameter_dict['userhosts'] }}' ${:wrapped-command-line}
{# Hack to deploy SSL certs via instance parameters -#} {# Hack to deploy SSL certs via instance parameters -#}
{% for zodb in zodb_dict.itervalues() -%} {% for zodb in zodb_dict.itervalues() -%}
...@@ -351,6 +359,10 @@ configuration-file = {{ '${' ~ conf_name ~ ':rendered}' }} ...@@ -351,6 +359,10 @@ configuration-file = {{ '${' ~ conf_name ~ ':rendered}' }}
{%- if wsgi %} {%- if wsgi %}
port = {{ port }} port = {{ port }}
{%- endif %} {%- endif %}
hash-files =
${:configuration-file}
hash-existing-files =
${buildout:directory}/software_release/buildout.cfg
[{{ section("promise-" ~ name) }}] [{{ section("promise-" ~ name) }}]
<= monitor-promise-base <= monitor-promise-base
...@@ -359,19 +371,6 @@ name = {{ name }}.py ...@@ -359,19 +371,6 @@ name = {{ name }}.py
config-hostname = {{ ipv4 }} config-hostname = {{ ipv4 }}
config-port = {{ port }} config-port = {{ port }}
{% set extra_path_list = [] -%}
{% set shell_escaped_extra_path_list = [] -%}
{% for line in parameter_dict['extra-path-list'].splitlines() -%}
{% set line = line.strip() -%}
{% do extra_path_list.append(line) -%}
{% do shell_escaped_extra_path_list.append(line.replace("\x27", "\x27\\\x27\x27")) -%}
{% endfor -%}
[{{ section("promise-" ~ name ~ "-is-running-actual-product") }}]
<= monitor-promise-base
module = check_command_execute
name = {{ name }}-is-running-actual-product.py
config-command = '{{ parameter_dict['bin-directory'] }}/is-process-older-than-dependency-set' '{{ "${" ~ conf_parameter_name ~ ":pid-file}" }}' {{ " ".join(shell_escaped_extra_path_list) }}
{% if use_ipv6 -%} {% if use_ipv6 -%}
[{{ zope_tunnel_section_name }}] [{{ zope_tunnel_section_name }}]
< = ipv6toipv4-base < = ipv6toipv4-base
...@@ -557,6 +556,7 @@ hard to guess. ...@@ -557,6 +556,7 @@ hard to guess.
hosts-dict = {{ dumps(hosts_dict) }} hosts-dict = {{ dumps(hosts_dict) }}
monitor-base-url = ${monitor-publish-parameters:monitor-base-url} monitor-base-url = ${monitor-publish-parameters:monitor-base-url}
test-runner-address-list = {{ dumps(test_runner_address_list) }} test-runner-address-list = {{ dumps(test_runner_address_list) }}
software-release-url = ${slap-connection:software-release-url}
[monitor-instance-parameter] [monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }} monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
......
...@@ -56,13 +56,17 @@ openssl-location = {{ openssl_location }} ...@@ -56,13 +56,17 @@ openssl-location = {{ openssl_location }}
[dynamic-template-balancer-parameters] [dynamic-template-balancer-parameters]
<= default-dynamic-template-parameters <= default-dynamic-template-parameters
apache = {{ apache_location }}
openssl = {{ openssl_location }} openssl = {{ openssl_location }}
haproxy = {{ haproxy_location }} haproxy = {{ haproxy_location }}
rsyslogd = {{ rsyslogd_location }}
socat = {{ socat_location }}
apachedex-location = {{ bin_directory }}/apachedex apachedex-location = {{ bin_directory }}/apachedex
run-apachedex-location = {{ bin_directory }}/runApacheDex run-apachedex-location = {{ bin_directory }}/runApacheDex
promise-check-apachedex-result = {{ bin_directory }}/check-apachedex-result promise-check-apachedex-result = {{ bin_directory }}/check-apachedex-result
template-haproxy-cfg = {{ template_haproxy_cfg }} template-haproxy-cfg = {{ template_haproxy_cfg }}
template-rsyslogd-cfg = {{ template_rsyslogd_cfg }}
# XXX: only used in software/slapos-master:
apache = {{ apache_location }}
template-apache-conf = {{ template_apache_conf }} template-apache-conf = {{ template_apache_conf }}
[dynamic-template-balancer] [dynamic-template-balancer]
...@@ -103,7 +107,7 @@ link-binary = {{ dumps(zope_link_binary) }} ...@@ -103,7 +107,7 @@ link-binary = {{ dumps(zope_link_binary) }}
fonts = {{ dumps(zope_fonts) }} fonts = {{ dumps(zope_fonts) }}
fontconfig-includes = {{ dumps(zope_fontconfig_includes) }} fontconfig-includes = {{ dumps(zope_fontconfig_includes) }}
template-fonts-conf = {{ dumps(template_fonts_conf) }} template-fonts-conf = {{ dumps(template_fonts_conf) }}
userhosts = {{ userhosts_location }}/bin/userhosts userhosts = {{ userhosts_location }}/lib/userhosts.so
site-zcml = {{ site_zcml }} site-zcml = {{ site_zcml }}
extra-path-list = {{ dumps(extra_path_list) }} extra-path-list = {{ dumps(extra_path_list) }}
matplotlibrc = {{ matplotlibrc_location }} matplotlibrc = {{ matplotlibrc_location }}
......
module(
load="imuxsock"
SysSock.Name="{{ parameter_dict['log-socket'] }}")
# Just simply output the raw line without any additional information, as
# haproxy emits enough information by itself
# Also cut out first empty space in msg, which is related to rsyslogd
# internal and end up cutting on 8k, as it's default of $MaxMessageSize
template(name="rawoutput" type="string" string="%msg:2:8192%\n")
$ActionFileDefaultTemplate rawoutput
$FileCreateMode 0600
$DirCreateMode 0700
$Umask 0022
$WorkDirectory {{ parameter_dict['spool-directory'] }}
local0.=info {{ parameter_dict['access-log-file'] }}
local0.warning {{ parameter_dict['error-log-file'] }}
...@@ -50,7 +50,3 @@ template = ${:_profile_base_location_}/nxdtest/${:filename} ...@@ -50,7 +50,3 @@ template = ${:_profile_base_location_}/nxdtest/${:filename}
context = context =
section buildout buildout section buildout buildout
section nxdtest nxdtest section nxdtest nxdtest
[versions]
slapos.recipe.template = 4.4
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# not need these here). # not need these here).
[pbsready] [pbsready]
filename = pbsready.cfg.in filename = pbsready.cfg.in
md5sum = 2bd6f853ace04ea84dffe29acfce92df md5sum = 4b0f914a54c9be5bff2b86f3416f4584
[pbsready-import] [pbsready-import]
filename = pbsready-import.cfg.in filename = pbsready-import.cfg.in
......
...@@ -177,7 +177,6 @@ template = inline: ...@@ -177,7 +177,6 @@ template = inline:
Port $${sshd-port:port} Port $${sshd-port:port}
ListenAddress $${slap-network-information:global-ipv6} ListenAddress $${slap-network-information:global-ipv6}
Protocol 2 Protocol 2
UsePrivilegeSeparation no
HostKey $${directory:ssh}/server_key.rsa HostKey $${directory:ssh}/server_key.rsa
AuthorizedKeysFile $${directory:ssh}/.ssh/authorized_keys AuthorizedKeysFile $${directory:ssh}/.ssh/authorized_keys
PasswordAuthentication no PasswordAuthentication no
...@@ -208,7 +207,7 @@ mode = 700 ...@@ -208,7 +207,7 @@ mode = 700
[sshd-graceful] [sshd-graceful]
recipe = slapos.cookbook:wrapper recipe = slapos.cookbook:wrapper
command-line = $${directory:bin}/killpidfromfile $${resilient-sshd-config:path_pid} SIGHUP command-line = $${rootdirectory:bin}/killpidfromfile $${resilient-sshd-config:path_pid} SIGHUP
wrapper-path = $${basedirectory:scripts}/sshd-graceful wrapper-path = $${basedirectory:scripts}/sshd-graceful
[sshd-promise] [sshd-promise]
......
...@@ -136,7 +136,7 @@ eggs = ...@@ -136,7 +136,7 @@ eggs =
[versions] [versions]
setuptools = 44.0.0 setuptools = 44.0.0
# Use SlapOS patched zc.buildout # Use SlapOS patched zc.buildout
zc.buildout = 2.7.1+slapos009 zc.buildout = 2.7.1+slapos010
# Use SlapOS patched zc.recipe.egg (zc.recipe.egg 2.x is for Buildout 2) # Use SlapOS patched zc.recipe.egg (zc.recipe.egg 2.x is for Buildout 2)
zc.recipe.egg = 2.0.3+slapos003 zc.recipe.egg = 2.0.3+slapos003
# Use own version of h.r.download to be able to open .xz and .lz archives # Use own version of h.r.download to be able to open .xz and .lz archives
...@@ -191,7 +191,7 @@ scandir = 1.10.0 ...@@ -191,7 +191,7 @@ scandir = 1.10.0
setuptools-dso = 1.7 setuptools-dso = 1.7
rubygemsrecipe = 0.3.0 rubygemsrecipe = 0.3.0
six = 1.12.0 six = 1.12.0
slapos.cookbook = 1.0.167 slapos.cookbook = 1.0.171
slapos.core = 1.6.3 slapos.core = 1.6.3
slapos.extension.strip = 0.4 slapos.extension.strip = 0.4
slapos.extension.shared = 1.0 slapos.extension.shared = 1.0
...@@ -199,6 +199,7 @@ slapos.libnetworkcache = 0.20 ...@@ -199,6 +199,7 @@ slapos.libnetworkcache = 0.20
slapos.rebootstrap = 4.5 slapos.rebootstrap = 4.5
slapos.recipe.build = 0.46 slapos.recipe.build = 0.46
slapos.recipe.cmmi = 0.16 slapos.recipe.cmmi = 0.16
slapos.recipe.template = 4.5
slapos.toolbox = 0.112 slapos.toolbox = 0.112
stevedore = 1.21.0 stevedore = 1.21.0
subprocess32 = 3.5.3 subprocess32 = 3.5.3
......
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