Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Titouan Soulard
slapos
Commits
3fba7c6e
Commit
3fba7c6e
authored
Jul 13, 2023
by
Thomas Gambier
🚴🏼
Browse files
Options
Browse Files
Download
Plain Diff
Update Release Candidate
parents
cbf7bd47
70b7c017
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
343 additions
and
49 deletions
+343
-49
setup.py
setup.py
+1
-1
slapos/recipe/erp5testnode/__init__.py
slapos/recipe/erp5testnode/__init__.py
+1
-0
slapos/recipe/erp5testnode/template/erp5testnode.cfg.in
slapos/recipe/erp5testnode/template/erp5testnode.cfg.in
+2
-1
software/slapos-sr-testing/buildout.hash.cfg
software/slapos-sr-testing/buildout.hash.cfg
+1
-1
software/slapos-sr-testing/instance.cfg
software/slapos-sr-testing/instance.cfg
+10
-3
software/theia/buildout.hash.cfg
software/theia/buildout.hash.cfg
+5
-5
software/theia/instance-export.cfg.jinja.in
software/theia/instance-export.cfg.jinja.in
+2
-0
software/theia/instance-import.cfg.jinja.in
software/theia/instance-import.cfg.jinja.in
+2
-0
software/theia/instance-theia.cfg.jinja.in
software/theia/instance-theia.cfg.jinja.in
+9
-6
software/theia/instance.cfg.in
software/theia/instance.cfg.in
+2
-1
software/theia/slapos_standalone_script.py.jinja
software/theia/slapos_standalone_script.py.jinja
+33
-15
software/theia/test/test.py
software/theia/test/test.py
+18
-0
software/theia/test/test_resiliency.py
software/theia/test/test_resiliency.py
+68
-15
software/theia/test/upgrade_tests.py
software/theia/test/upgrade_tests.py
+188
-0
stack/slapos.cfg
stack/slapos.cfg
+1
-1
No files found.
setup.py
View file @
3fba7c6e
...
@@ -28,7 +28,7 @@ from setuptools import setup, find_packages
...
@@ -28,7 +28,7 @@ from setuptools import setup, find_packages
import
glob
import
glob
import
os
import
os
version
=
'1.0.32
6
'
version
=
'1.0.32
9
'
name
=
'slapos.cookbook'
name
=
'slapos.cookbook'
long_description
=
open
(
"README.rst"
).
read
()
long_description
=
open
(
"README.rst"
).
read
()
...
...
slapos/recipe/erp5testnode/__init__.py
View file @
3fba7c6e
...
@@ -58,6 +58,7 @@ class Recipe(GenericBaseRecipe):
...
@@ -58,6 +58,7 @@ class Recipe(GenericBaseRecipe):
"
\
n
path_list = %s"
%
","
.
join
(
software_path_list
)
"
\
n
path_list = %s"
%
","
.
join
(
software_path_list
)
CONFIG
[
'computer_id'
]
=
self
.
buildout
[
'slap-connection'
][
'computer-id'
]
CONFIG
[
'computer_id'
]
=
self
.
buildout
[
'slap-connection'
][
'computer-id'
]
CONFIG
[
'server_url'
]
=
self
.
buildout
[
'slap-connection'
][
'server-url'
]
CONFIG
[
'server_url'
]
=
self
.
buildout
[
'slap-connection'
][
'server-url'
]
CONFIG
[
'shared_part_list'
]
=
CONFIG
[
'shared_part_list'
].
replace
(
'
\
n
'
,
'
\
n
'
)
configuration_file
=
self
.
createFile
(
configuration_file
=
self
.
createFile
(
self
.
options
[
'configuration-file'
],
self
.
options
[
'configuration-file'
],
self
.
substituteTemplate
(
self
.
substituteTemplate
(
...
...
slapos/recipe/erp5testnode/template/erp5testnode.cfg.in
View file @
3fba7c6e
...
@@ -2,7 +2,8 @@
...
@@ -2,7 +2,8 @@
slapos_directory = %(slapos_directory)s
slapos_directory = %(slapos_directory)s
working_directory = %(working_directory)s
working_directory = %(working_directory)s
test_suite_directory = %(test_suite_directory)s
test_suite_directory = %(test_suite_directory)s
shared_part_list = %(shared_part_list)s
shared_part_list =
%(shared_part_list)s
software_directory = %(software_directory)s
software_directory = %(software_directory)s
log_directory = %(log_directory)s
log_directory = %(log_directory)s
run_directory = %(run_directory)s
run_directory = %(run_directory)s
...
...
software/slapos-sr-testing/buildout.hash.cfg
View file @
3fba7c6e
...
@@ -15,4 +15,4 @@
...
@@ -15,4 +15,4 @@
[template]
[template]
filename = instance.cfg
filename = instance.cfg
md5sum =
06379c0ed1fe0df409c7b8f61fc218eb
md5sum =
ed0f91f39d5eda903938aa527625f40d
software/slapos-sr-testing/instance.cfg
View file @
3fba7c6e
...
@@ -28,13 +28,20 @@ test-working-dir = ${buildout:directory}/tmp
...
@@ -28,13 +28,20 @@ test-working-dir = ${buildout:directory}/tmp
nxdtest-working-dir = ${:var}/nxdtest
nxdtest-working-dir = ${:var}/nxdtest
[slapos-test-runner-nxdtest-environment.sh]
[slapos-test-runner-nxdtest-environment.sh]
recipe = slapos.recipe.template
recipe = slapos.recipe.template
:jinja2
output = ${directory:etc}/${:_buildout_section_name_}
output = ${directory:etc}/${:_buildout_section_name_}
PATH={{ buildout['bin-directory'] }}:{{ curl_location }}/bin:{{ faketime_location }}/bin:{{ openssl_location }}/bin:/usr/bin:/bin
context =
section slap slap-configuration
key ipv6_random slap-configuration:ipv6-random
{%- raw %}
inline =
inline =
export PATH=
{{ buildout['bin-directory'] }}:{{ curl_location }}/bin:{{ faketime_location }}/bin:{{ openssl_location }}/bin:/usr/bin:/bin
export PATH=
${:PATH}
export SLAPOS_TEST_IPV4=${slap-configuration:ipv4-random}
export SLAPOS_TEST_IPV4=${slap-configuration:ipv4-random}
export SLAPOS_TEST_IPV6=
${slap-configuration:ipv6-random
}
export SLAPOS_TEST_IPV6=
{{ slap.get('ipv6-range-network') or ipv6_random }
}
export SLAPOS_TEST_WORKING_DIR=${directory:test-working-dir}
export SLAPOS_TEST_WORKING_DIR=${directory:test-working-dir}
{%- endraw %}
[slapos-test-runner-dot-nxdtest]
[slapos-test-runner-dot-nxdtest]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
...
...
software/theia/buildout.hash.cfg
View file @
3fba7c6e
...
@@ -15,19 +15,19 @@
...
@@ -15,19 +15,19 @@
[instance-theia]
[instance-theia]
_update_hash_filename_ = instance-theia.cfg.jinja.in
_update_hash_filename_ = instance-theia.cfg.jinja.in
md5sum =
a9d4ace568acdd5002d587816ab91737
md5sum =
b406265f591f54a0d5a6aa3ff8522764
[instance]
[instance]
_update_hash_filename_ = instance.cfg.in
_update_hash_filename_ = instance.cfg.in
md5sum =
08b8aa2b7f59ac0e4e5d4ca18005493
7
md5sum =
f322033a7670b9be29b1bf1bf9024b8
7
[instance-import]
[instance-import]
_update_hash_filename_ = instance-import.cfg.jinja.in
_update_hash_filename_ = instance-import.cfg.jinja.in
md5sum =
a343818079d4fc106594e5850cc1853
a
md5sum =
6520d2aa0c1c6094cbf276080594ec1
a
[instance-export]
[instance-export]
_update_hash_filename_ = instance-export.cfg.jinja.in
_update_hash_filename_ = instance-export.cfg.jinja.in
md5sum =
84ceb4c9ee0f07fce8518ef7517ce1d4
md5sum =
bb6d26c56b4bb9cf553c130fdd51000d
[instance-resilient]
[instance-resilient]
_update_hash_filename_ = instance-resilient.cfg.jinja
_update_hash_filename_ = instance-resilient.cfg.jinja
...
@@ -35,7 +35,7 @@ md5sum = ad9499e7355ded4975ad313442cecb7a
...
@@ -35,7 +35,7 @@ md5sum = ad9499e7355ded4975ad313442cecb7a
[slapos-standalone-script]
[slapos-standalone-script]
_update_hash_filename_ = slapos_standalone_script.py.jinja
_update_hash_filename_ = slapos_standalone_script.py.jinja
md5sum =
6792d29057db35ea69b01e72a5c913e3
md5sum =
3572b3fa458505ae25ebcea9b1ed3267
[theia-common]
[theia-common]
_update_hash_filename_ = theia_common.py
_update_hash_filename_ = theia_common.py
...
...
software/theia/instance-export.cfg.jinja.in
View file @
3fba7c6e
...
@@ -42,6 +42,7 @@ context =
...
@@ -42,6 +42,7 @@ context =
raw slapos_cfg $${directory:runner}/etc/slapos.cfg
raw slapos_cfg $${directory:runner}/etc/slapos.cfg
raw project_path $${directory:project}
raw project_path $${directory:project}
raw public_path $${directory:frontend-static-public}
raw public_path $${directory:frontend-static-public}
raw statefiles_path $${directory:statefiles}
key exitfile :exitcode-file
key exitfile :exitcode-file
key errorfile :error-file
key errorfile :error-file
{%- raw %}
{%- raw %}
...
@@ -55,6 +56,7 @@ inline =
...
@@ -55,6 +56,7 @@ inline =
--cfg {{ slapos_cfg }} \
--cfg {{ slapos_cfg }} \
--dirs {{ project_path }} \
--dirs {{ project_path }} \
--dirs {{ public_path }} \
--dirs {{ public_path }} \
--dirs {{ statefiles_path }} \
--exitfile {{ exitfile }} \
--exitfile {{ exitfile }} \
--errorfile {{ errorfile }}
--errorfile {{ errorfile }}
{%- endraw %}
{%- endraw %}
...
...
software/theia/instance-import.cfg.jinja.in
View file @
3fba7c6e
...
@@ -102,6 +102,7 @@ context =
...
@@ -102,6 +102,7 @@ context =
raw slapos_cfg $${directory:runner}/etc/slapos.cfg
raw slapos_cfg $${directory:runner}/etc/slapos.cfg
raw project_path $${directory:project}
raw project_path $${directory:project}
raw public_path $${directory:frontend-static-public}
raw public_path $${directory:frontend-static-public}
raw statefiles_path $${directory:statefiles}
key exitfile :exitcode-file
key exitfile :exitcode-file
key errorfile :error-file
key errorfile :error-file
{%- raw %}
{%- raw %}
...
@@ -122,6 +123,7 @@ inline =
...
@@ -122,6 +123,7 @@ inline =
--cfg {{ slapos_cfg }} \
--cfg {{ slapos_cfg }} \
--dirs {{ project_path }} \
--dirs {{ project_path }} \
--dirs {{ public_path }} \
--dirs {{ public_path }} \
--dirs {{ statefiles_path }} \
--exitfile {{ exitfile }} \
--exitfile {{ exitfile }} \
--errorfile {{ errorfile }}
--errorfile {{ errorfile }}
{%- endraw %}
{%- endraw %}
...
...
software/theia/instance-theia.cfg.jinja.in
View file @
3fba7c6e
...
@@ -38,7 +38,7 @@ additional-url = $${remote-additional-frontend:connection-secure_access}
...
@@ -38,7 +38,7 @@ additional-url = $${remote-additional-frontend:connection-secure_access}
username = $${frontend-instance-password:username}
username = $${frontend-instance-password:username}
password = $${frontend-instance-password:passwd}
password = $${frontend-instance-password:passwd}
backend-url = $${frontend-instance:url}
backend-url = $${frontend-instance:url}
ipv6 = {{ ipv6_
random
}}
ipv6 = {{ ipv6_
theia
}}
[directory]
[directory]
recipe = slapos.cookbook:mkdirectory
recipe = slapos.cookbook:mkdirectory
...
@@ -50,6 +50,7 @@ bin = $${:home}/bin
...
@@ -50,6 +50,7 @@ bin = $${:home}/bin
tmp = $${:home}/tmp
tmp = $${:home}/tmp
dot-theia = $${:home}/.theia/
dot-theia = $${:home}/.theia/
pidfiles = $${:var}/run
pidfiles = $${:var}/run
statefiles = $${:var}/state
services = $${:etc}/service
services = $${:etc}/service
runner = $${:srv}/runner
runner = $${:srv}/runner
...
@@ -227,7 +228,7 @@ storage-path = $${buildout:parts-directory}/.$${:_buildout_section_name_}
...
@@ -227,7 +228,7 @@ storage-path = $${buildout:parts-directory}/.$${:_buildout_section_name_}
recipe = slapos.cookbook:free_port
recipe = slapos.cookbook:free_port
minimum = 3000
minimum = 3000
maximum = 3100
maximum = 3100
ip = {{ ipv6_
random
}}
ip = {{ ipv6_
theia
}}
[frontend-instance-certificate]
[frontend-instance-certificate]
recipe = plone.recipe.command
recipe = plone.recipe.command
...
@@ -421,7 +422,7 @@ inline =
...
@@ -421,7 +422,7 @@ inline =
#!/bin/sh
#!/bin/sh
export HOME=$${directory:home}
export HOME=$${directory:home}
export PATH=${cli-utilities:PATH}:$HOME/.cargo/bin:$HOME/.local/bin:$PATH
export PATH=${cli-utilities:PATH}:$HOME/.cargo/bin:$HOME/.local/bin:$PATH
export IPV6_SLAPRUNNER={{ ipv6_
random
}}
export IPV6_SLAPRUNNER={{ ipv6_
theia
}}
# Theia Backend
# Theia Backend
# -------------
# -------------
...
@@ -566,7 +567,7 @@ ip = {{ ipv4_random }}
...
@@ -566,7 +567,7 @@ ip = {{ ipv4_random }}
[slapos-standalone-config]
[slapos-standalone-config]
ipv4 = {{ ipv4_random }}
ipv4 = {{ ipv4_random }}
ipv6 = {{
ipv6_random
}}
ipv6 = {{
slap_resource.get('ipv6-range-network') or ipv6_theia
}}
port = $${slapos-standalone-port:port}
port = $${slapos-standalone-port:port}
base-directory = $${directory:runner}
base-directory = $${directory:runner}
software-root = $${directory:runner}/software
software-root = $${directory:runner}/software
...
@@ -589,7 +590,8 @@ inline =
...
@@ -589,7 +590,8 @@ inline =
[slapos-standalone-script]
[slapos-standalone-script]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
output = $${directory:bin}/$${:_buildout_section_name_}
output = $${directory:bin}/$${:_buildout_section_name_}
embedded-request-exitcode-file = $${directory:etc}/embedded-request-exitcode
embedded-request-exitcode-file = $${directory:statefiles}/embedded-request.exitcode
standalone-ran-before-flag = $${directory:statefiles}/standalone-ran-before.flag
shared-part-list =
shared-part-list =
{{ """${buildout:shared-part-list}""" | indent(2) }}
{{ """${buildout:shared-part-list}""" | indent(2) }}
context =
context =
...
@@ -599,11 +601,12 @@ context =
...
@@ -599,11 +601,12 @@ context =
key request_script_template request-script-example:inline
key request_script_template request-script-example:inline
key shared_part_list :shared-part-list
key shared_part_list :shared-part-list
key embedded_request_exitcode_file :embedded-request-exitcode-file
key embedded_request_exitcode_file :embedded-request-exitcode-file
key standalone_ran_before_flag :standalone-ran-before-flag
key embedded_instance_config embedded-instance-config:output
key embedded_instance_config embedded-instance-config:output
key home_path directory:home
key home_path directory:home
key forward_frontend_requests :forward-frontend-requests
key forward_frontend_requests :forward-frontend-requests
section slap_connection slap-connection
section slap_connection slap-connection
section
slapos_standalone_
config slapos-standalone-config
section config slapos-standalone-config
forward-frontend-requests = {{ parameter_dict['forward-slapos-frontend-requests'] }}
forward-frontend-requests = {{ parameter_dict['forward-slapos-frontend-requests'] }}
url = ${slapos-standalone-script:output}
url = ${slapos-standalone-script:output}
...
...
software/theia/instance.cfg.in
View file @
3fba7c6e
...
@@ -37,8 +37,9 @@ context =
...
@@ -37,8 +37,9 @@ context =
key parameter_dict slap-configuration:configuration
key parameter_dict slap-configuration:configuration
key root_title slap-configuration:root-instance-title
key root_title slap-configuration:root-instance-title
key partition_root_path buildout:directory
key partition_root_path buildout:directory
key ipv6_
random
slap-configuration:ipv6-random
key ipv6_
theia
slap-configuration:ipv6-random
key ipv4_random slap-configuration:ipv4-random
key ipv4_random slap-configuration:ipv4-random
section slap_resource slap-configuration
import os os
import os os
import json json
import json json
default-parameters =
default-parameters =
...
...
software/theia/slapos_standalone_script.py.jinja
View file @
3fba7c6e
...
@@ -70,23 +70,23 @@ def setupStandalone():
...
@@ -70,23 +70,23 @@ def setupStandalone():
shared_parts = {{ repr(shared_part_list) }}
shared_parts = {{ repr(shared_part_list) }}
shared_part_list = [x.strip() for x in shared_parts.splitlines() if x.strip()]
shared_part_list = [x.strip() for x in shared_parts.splitlines() if x.strip()]
standalone = slapos.slap.standalone.StandaloneSlapOS(
standalone = slapos.slap.standalone.StandaloneSlapOS(
{{ repr(
slapos_standalone_
config['base-directory']) }},
{{ repr(config['base-directory']) }},
{{ repr(
slapos_standalone_
config['ipv4']) }},
{{ repr(config['ipv4']) }},
{{
slapos_standalone_
config['port'] }},
{{ config['port'] }},
computer_id={{ repr(
slapos_standalone_
config['computer-id']) }},
computer_id={{ repr(config['computer-id']) }},
shared_part_list=shared_part_list,
shared_part_list=shared_part_list,
software_root={{ repr(
slapos_standalone_
config['software-root']) }},
software_root={{ repr(config['software-root']) }},
instance_root={{ repr(
slapos_standalone_
config['instance-root']) }},
instance_root={{ repr(config['instance-root']) }},
partition_forward_configuration=partition_forward_configuration,
partition_forward_configuration=partition_forward_configuration,
slapos_bin={{ repr(
slapos_standalone_
config['slapos-bin']) }},
slapos_bin={{ repr(config['slapos-bin']) }},
local_software_release_root={{ repr(
slapos_standalone_
config['local-software-release-root']) }},
local_software_release_root={{ repr(config['local-software-release-root']) }},
)
)
standalone.start()
standalone.start()
try:
try:
partition_count = 20
partition_count = 20
logging.info("Standalone SlapOS: Formatting %d partitions", partition_count)
logging.info("Standalone SlapOS: Formatting %d partitions", partition_count)
standalone.format(partition_count, {{ repr(
slapos_standalone_config['ipv4']) }}, {{ repr(slapos_standalone_
config['ipv6']) }})
standalone.format(partition_count, {{ repr(
config['ipv4']) }}, {{ repr(
config['ipv6']) }})
logging.info("Standalone SlapOS for computer `%s` started", {{ repr(
slapos_standalone_
config['computer-id']) }})
logging.info("Standalone SlapOS for computer `%s` started", {{ repr(config['computer-id']) }})
# Run instance at least once, to start the supervisor managing instances.
# Run instance at least once, to start the supervisor managing instances.
try:
try:
standalone.waitForInstance(max_retry=0)
standalone.waitForInstance(max_retry=0)
...
@@ -153,10 +153,28 @@ def main():
...
@@ -153,10 +153,28 @@ def main():
with setupStandalone() as standalone:
with setupStandalone() as standalone:
config_json_file = {{ repr(embedded_instance_config) }}
config_json_file = {{ repr(embedded_instance_config) }}
done_file = config_json_file + '.done'
if not os.path.exists(done_file):
# backwards compatibility
with open(done_file, 'w'): pass
old_flag_file = config_json_file + '.done'
old_exitcode_file = os.path.join(
{{ repr(home_path) }}, 'etc', 'embedded-request-exitcode')
# new state filesstandalone_ran_before_flag
standalone_ran_before_flag = {{ repr(standalone_ran_before_flag) }}
exitcode_file = {{ repr(embedded_request_exitcode_file) }}
# backwards compatibility
if os.path.exists(old_flag_file):
logging.info("Moving old %s to %s", old_flag_file, standalone_ran_before_flag)
os.rename(old_flag_file, standalone_ran_before_flag)
if os.path.exists(old_exitcode_file):
logging.info("Moving old %s to %s", old_exitcode_file, exitcode_file)
os.rename(old_exitcode_file, exitcode_file)
elif not os.path.exists(standalone_ran_before_flag):
logging.info("First run!")
logging.info("Creating flag file %s", standalone_ran_before_flag)
with open(standalone_ran_before_flag, 'x'): pass
try:
try:
config = parseEmbeddedInstanceConfig(config_json_file)
config = parseEmbeddedInstanceConfig(config_json_file)
except Exception:
except Exception:
...
@@ -172,14 +190,14 @@ def main():
...
@@ -172,14 +190,14 @@ def main():
'SLAPOS_CONFIGURATION': standalone._slapos_config,
'SLAPOS_CONFIGURATION': standalone._slapos_config,
'SLAPOS_CLIENT_CONFIGURATION': standalone._slapos_config,
'SLAPOS_CLIENT_CONFIGURATION': standalone._slapos_config,
})
})
with open(
{{ repr(embedded_request_exitcode_file) }}
, 'w') as f:
with open(
exitcode_file
, 'w') as f:
f.write(str(exitcode))
f.write(str(exitcode))
except Exception:
except Exception:
logging.info("Failed to request embedded instance", exc_info=True)
logging.info("Failed to request embedded instance", exc_info=True)
s = socket.socket(socket.AF_UNIX)
s = socket.socket(socket.AF_UNIX)
s.bind({{ repr('\0' +
slapos_standalone_
config['abstract-socket-path']) }})
s.bind({{ repr('\0' + config['abstract-socket-path']) }})
s.listen(5)
s.listen(5)
logging.info("Standalone SlapOS ready")
logging.info("Standalone SlapOS ready")
...
...
software/theia/test/test.py
View file @
3fba7c6e
...
@@ -34,6 +34,7 @@ import subprocess
...
@@ -34,6 +34,7 @@ import subprocess
import
sqlite3
import
sqlite3
import
time
import
time
import
netaddr
import
pexpect
import
pexpect
import
psutil
import
psutil
import
requests
import
requests
...
@@ -241,6 +242,19 @@ class TestTheia(TheiaTestCase):
...
@@ -241,6 +242,19 @@ class TestTheia(TheiaTestCase):
self
.
assertIn
(
b'slaprunner'
,
self
.
captureSlapos
(
'proxy'
,
'show'
))
self
.
assertIn
(
b'slaprunner'
,
self
.
captureSlapos
(
'proxy'
,
'show'
))
self
.
assertIn
(
b'slaprunner'
,
self
.
captureSlapos
(
'computer'
,
'list'
))
self
.
assertIn
(
b'slaprunner'
,
self
.
captureSlapos
(
'computer'
,
'list'
))
def
test_ipv6_range
(
self
):
proxy_path
=
self
.
getPath
(
'srv'
,
'runner'
,
'var'
,
'proxy.db'
)
query
=
"SELECT partition_reference, address FROM partition_network%s"
%
DB_VERSION
with
sqlite3
.
connect
(
proxy_path
)
as
db
:
rows
=
db
.
execute
(
query
).
fetchall
()
partitions
=
set
(
p
for
p
,
_
in
rows
)
ipv6
=
set
(
addr
for
_
,
addr
in
rows
if
netaddr
.
valid_ipv6
(
addr
))
# Check that each partition has a different IPv6
self
.
assertEqual
(
len
(
partitions
),
len
(
ipv6
))
# Check that no partition has the same IPv6 as theia
self
.
assertNotIn
(
self
.
connection_parameters
[
'ipv6'
],
ipv6
)
class
TestTheiaWithNonAsciiInstanceName
(
TestTheia
):
class
TestTheiaWithNonAsciiInstanceName
(
TestTheia
):
default_partition_reference
=
'💥'
default_partition_reference
=
'💥'
...
@@ -524,6 +538,10 @@ class ResilientTheiaMixin(object):
...
@@ -524,6 +538,10 @@ class ResilientTheiaMixin(object):
def
getPartitionPath
(
cls
,
instance_type
=
'export'
,
*
paths
):
def
getPartitionPath
(
cls
,
instance_type
=
'export'
,
*
paths
):
return
os
.
path
.
join
(
cls
.
slap
.
_instance_root
,
cls
.
getPartitionId
(
instance_type
),
*
paths
)
return
os
.
path
.
join
(
cls
.
slap
.
_instance_root
,
cls
.
getPartitionId
(
instance_type
),
*
paths
)
@
classmethod
def
getPath
(
cls
,
*
components
):
# patch getPath
return
cls
.
getPartitionPath
(
'export'
,
*
components
)
@
classmethod
@
classmethod
def
_getSlapos
(
cls
,
instance_type
=
'export'
):
def
_getSlapos
(
cls
,
instance_type
=
'export'
):
return
cls
.
getPartitionPath
(
instance_type
,
'srv'
,
'runner'
,
'bin'
,
'slapos'
)
return
cls
.
getPartitionPath
(
instance_type
,
'srv'
,
'runner'
,
'bin'
,
'slapos'
)
...
...
software/theia/test/test_resiliency.py
View file @
3fba7c6e
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
import
errno
import
errno
import
json
import
os
import
os
import
re
import
re
import
shutil
import
shutil
...
@@ -38,11 +39,15 @@ import requests
...
@@ -38,11 +39,15 @@ import requests
from
slapos.proxy.db_version
import
DB_VERSION
from
slapos.proxy.db_version
import
DB_VERSION
from
slapos.slap.slap
import
DEFAULT_SOFTWARE_TYPE
from
slapos.testing.testcase
import
SlapOSNodeCommandError
,
installSoftwareUrlList
from
slapos.testing.testcase
import
SlapOSNodeCommandError
,
installSoftwareUrlList
import
test
from
test
import
TheiaTestCase
,
ResilientTheiaMixin
,
theia_software_release_url
from
test
import
TheiaTestCase
,
ResilientTheiaMixin
,
theia_software_release_url
dummy_software_url
=
os
.
path
.
abspath
(
dummy_software_url
=
os
.
path
.
abspath
(
os
.
path
.
join
(
'resilience_dummy'
,
'software.cfg'
))
os
.
path
.
join
(
'resilience_dummy'
,
'software.cfg'
))
...
@@ -82,8 +87,7 @@ class ResilientTheiaTestCase(ResilientTheiaMixin, TheiaTestCase):
...
@@ -82,8 +87,7 @@ class ResilientTheiaTestCase(ResilientTheiaMixin, TheiaTestCase):
cls
.
checkSlapos
(
'node'
,
'instance'
,
instance_type
=
instance_type
)
cls
.
checkSlapos
(
'node'
,
'instance'
,
instance_type
=
instance_type
)
@
classmethod
@
classmethod
def
_deployEmbeddedSoftware
(
cls
,
software_url
,
instance_name
,
retries
=
0
,
instance_type
=
'export'
):
def
_processEmbeddedSoftware
(
cls
,
retries
=
0
,
instance_type
=
'export'
):
cls
.
callSlapos
(
'supply'
,
software_url
,
'slaprunner'
,
instance_type
=
instance_type
)
for
_
in
range
(
retries
):
for
_
in
range
(
retries
):
try
:
try
:
output
=
cls
.
captureSlapos
(
'node'
,
'software'
,
instance_type
=
instance_type
,
stderr
=
subprocess
.
STDOUT
)
output
=
cls
.
captureSlapos
(
'node'
,
'software'
,
instance_type
=
instance_type
,
stderr
=
subprocess
.
STDOUT
)
...
@@ -96,6 +100,11 @@ class ResilientTheiaTestCase(ResilientTheiaMixin, TheiaTestCase):
...
@@ -96,6 +100,11 @@ class ResilientTheiaTestCase(ResilientTheiaMixin, TheiaTestCase):
print
(
"Wait before running slapos node software one last time"
)
print
(
"Wait before running slapos node software one last time"
)
time
.
sleep
(
120
)
time
.
sleep
(
120
)
cls
.
checkSlapos
(
'node'
,
'software'
,
instance_type
=
instance_type
)
cls
.
checkSlapos
(
'node'
,
'software'
,
instance_type
=
instance_type
)
@
classmethod
def
_deployEmbeddedSoftware
(
cls
,
software_url
,
instance_name
,
retries
=
0
,
instance_type
=
'export'
):
cls
.
callSlapos
(
'supply'
,
software_url
,
'slaprunner'
,
instance_type
=
instance_type
)
cls
.
_processEmbeddedSoftware
(
retries
,
instance_type
)
cls
.
callSlapos
(
'request'
,
instance_name
,
software_url
,
instance_type
=
instance_type
)
cls
.
callSlapos
(
'request'
,
instance_name
,
software_url
,
instance_type
=
instance_type
)
cls
.
_processEmbeddedInstance
(
retries
,
instance_type
)
cls
.
_processEmbeddedInstance
(
retries
,
instance_type
)
...
@@ -435,7 +444,8 @@ class TestTheiaExportAndImport(ResilienceMixin, ExportAndImportMixin, ResilientT
...
@@ -435,7 +444,8 @@ class TestTheiaExportAndImport(ResilienceMixin, ExportAndImportMixin, ResilientT
class
TakeoverMixin
(
ExportAndImportMixin
):
class
TakeoverMixin
(
ExportAndImportMixin
):
def
_getTakeoverUrlAndPassword
(
self
,
scope
=
"theia-1"
):
def
_getTakeoverUrlAndPassword
(
self
,
scope
=
"theia-1"
):
parameter_dict
=
self
.
computer_partition
.
getConnectionParameterDict
()
partition
=
self
.
requestDefaultInstance
()
# re-request for up-to-date info
parameter_dict
=
partition
.
getConnectionParameterDict
()
takeover_url
=
parameter_dict
[
"takeover-%s-url"
%
scope
]
takeover_url
=
parameter_dict
[
"takeover-%s-url"
%
scope
]
takeover_password
=
parameter_dict
[
"takeover-%s-password"
%
scope
]
takeover_password
=
parameter_dict
[
"takeover-%s-password"
%
scope
]
return
takeover_url
,
takeover_password
return
takeover_url
,
takeover_password
...
@@ -488,8 +498,18 @@ class TakeoverMixin(ExportAndImportMixin):
...
@@ -488,8 +498,18 @@ class TakeoverMixin(ExportAndImportMixin):
self
.
assertIn
(
"Success"
,
resp
.
text
,
"An Error occured: %s"
%
resp
.
text
)
self
.
assertIn
(
"Success"
,
resp
.
text
,
"An Error occured: %s"
%
resp
.
text
)
return
resp
.
text
return
resp
.
text
def
_doTakeover
(
self
):
# Takeover
takeover_url
,
takeover_password
=
self
.
_getTakeoverUrlAndPassword
()
self
.
_requestTakeover
(
takeover_url
,
takeover_password
)
# Wait for import instance to become export instance and new import to be allocated
# This also checks that all promises of theia instances succeed
self
.
slap
.
waitForInstance
(
self
.
instance_max_retry
)
self
.
computer_partition
=
self
.
requestDefaultInstance
()
class
TheiaSyncMixin
(
ResilienceMixin
,
TakeoverMixin
):
class
TheiaSyncMixin
(
TakeoverMixin
,
ResilienceMixin
):
def
_doSync
(
self
,
max_tries
=
None
,
wait_interval
=
None
):
def
_doSync
(
self
,
max_tries
=
None
,
wait_interval
=
None
):
max_tries
=
max_tries
or
self
.
backup_max_tries
max_tries
=
max_tries
or
self
.
backup_max_tries
wait_interval
=
wait_interval
or
self
.
backup_wait_interval
wait_interval
=
wait_interval
or
self
.
backup_wait_interval
...
@@ -537,17 +557,10 @@ class TestTheiaResilience(TheiaSyncMixin, ResilientTheiaTestCase):
...
@@ -537,17 +557,10 @@ class TestTheiaResilience(TheiaSyncMixin, ResilientTheiaTestCase):
def
_checkSync
(
self
):
def
_checkSync
(
self
):
# Check that ~/etc still contains everything it did before
# Check that ~/etc still contains everything it did before
etc_listdir
=
os
.
listdir
(
self
.
getPartitionPath
(
'import'
,
'etc'
))
etc_listdir
=
os
.
listdir
(
self
.
getPartitionPath
(
'import'
,
'etc'
))
self
.
assertTrue
(
set
(
self
.
etc_listdir
).
issubset
(
etc_listdir
))
try
:
self
.
assertTrue
(
set
(
self
.
etc_listdir
).
issubset
(
etc_listdir
))
def
_doTakeover
(
self
):
except
AssertionError
:
# Takeover
breakpoint
()
takeover_url
,
takeover_password
=
self
.
_getTakeoverUrlAndPassword
()
self
.
_requestTakeover
(
takeover_url
,
takeover_password
)
# Wait for import instance to become export instance and new import to be allocated
# This also checks that all promises of theia instances succeed
self
.
slap
.
waitForInstance
(
self
.
instance_max_retry
)
self
.
computer_partition
=
self
.
requestDefaultInstance
()
def
_checkTakeover
(
self
):
def
_checkTakeover
(
self
):
# Check that there is an export, import and frozen instance and get their new partition IDs
# Check that there is an export, import and frozen instance and get their new partition IDs
...
@@ -601,3 +614,43 @@ class TestTheiaFrontendForwarding(TheiaSyncMixin, ResilientTheiaTestCase):
...
@@ -601,3 +614,43 @@ class TestTheiaFrontendForwarding(TheiaSyncMixin, ResilientTheiaTestCase):
def
_doTakeover
(
self
):
def
_doTakeover
(
self
):
# do nothing
# do nothing
pass
pass
class
TestTheiaResilienceWithInitialInstance
(
TestTheiaResilience
,
test
.
TestTheiaWithEmbeddedInstance
):
backup_max_tries
=
70
backup_wait_interval
=
10
sr_url
=
dummy_software_url
sr_type
=
DEFAULT_SOFTWARE_TYPE
sr_config
=
{}
@
classmethod
def
getInstanceParameterDict
(
cls
,
sr_url
=
None
,
sr_type
=
None
,
sr_config
=
None
):
d
=
test
.
TestTheiaWithEmbeddedInstance
.
getInstanceParameterDict
.
__func__
(
cls
,
sr_url
,
sr_type
,
sr_config
)
d
.
update
(
autorun
=
'stopped'
)
return
d
def
_prepareExport
(
self
):
# Check that there is an export and import instance and get their partition IDs
self
.
export_id
=
self
.
getPartitionId
(
'export'
)
self
.
import_id
=
self
.
getPartitionId
(
'import'
)
# Remember content of ~/etc in the import theia
self
.
etc_listdir
=
os
.
listdir
(
self
.
getPartitionPath
(
'import'
,
'etc'
))
# Check initial embedded instance
test
.
TestTheiaWithEmbeddedInstance
.
test
(
self
)
self
.
_processEmbeddedSoftware
()
self
.
_processEmbeddedInstance
()
def
_checkTakeover
(
self
):
# Check takeover
TestTheiaResilience
.
_checkTakeover
(
self
)
# Check that embedded instance still exists
test
.
TestTheiaWithEmbeddedInstance
.
test
(
self
)
self
.
_processEmbeddedSoftware
()
self
.
_processEmbeddedInstance
()
software/theia/test/upgrade_tests.py
0 → 100644
View file @
3fba7c6e
import
json
import
os
from
slapos.testing.testcase
import
(
installSoftwareUrlList
,
makeModuleSetUpAndTestCaseClass
,
SlapOSNodeCommandError
,
)
import
test
import
test_resiliency
stable_software_url
=
"https://lab.nexedi.com/nexedi/slapos/raw/1.0.324/software/theia/software.cfg"
dev_software_url
=
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'software.cfg'
))
software_url_list
=
[
stable_software_url
,
dev_software_url
]
_
,
SlapOSInstanceTestCase
=
makeModuleSetUpAndTestCaseClass
(
stable_software_url
)
class
UpgradeTestCase
(
SlapOSInstanceTestCase
):
_current_software_url
=
stable_software_url
@
classmethod
def
getSoftwareURL
(
cls
):
return
cls
.
_current_software_url
@
classmethod
def
upgrade
(
cls
):
# request instance on dev software
cls
.
_current_software_url
=
dev_software_url
cls
.
logger
.
debug
(
'Requesting instance on dev software'
)
cls
.
requestDefaultInstance
()
# wait for slapos node instance
snapshot_name
=
"{}.{}.dev.setUpClass"
.
format
(
cls
.
__module__
,
cls
.
__name__
)
with
cls
.
_snapshotManager
(
snapshot_name
):
try
:
for
_
in
range
(
2
):
# propagation
cls
.
waitForInstance
()
cls
.
logger
.
debug
(
"Instance on dev software done"
)
except
BaseException
:
cls
.
logger
.
exception
(
"Error during instance on dev software"
)
raise
cls
.
computer_partition
=
cls
.
requestDefaultInstance
()
@
classmethod
def
beforeUpgrade
(
cls
):
pass
@
classmethod
def
setUpClass
(
cls
):
# request and instantiate with old software url
super
().
setUpClass
()
# before upgrade hook
cls
.
beforeUpgrade
()
# upgrade
cls
.
upgrade
()
def
setUpModule
():
installSoftwareUrlList
(
SlapOSInstanceTestCase
,
software_url_list
,
debug
=
SlapOSInstanceTestCase
.
_debug
,
)
class
TestTheia
(
UpgradeTestCase
,
test
.
TestTheia
):
pass
class
TestTheiaWithEmbeddedInstance
(
UpgradeTestCase
,
test
.
TestTheiaWithEmbeddedInstance
):
pass
class
TestTheiaResilientInterface
(
UpgradeTestCase
,
test
.
TestTheiaResilientInterface
):
pass
class
TestTheiaResilientWithEmbeddedInstance
(
UpgradeTestCase
,
test
.
TestTheiaResilientWithEmbeddedInstance
):
pass
class
TestTheiaResilienceWithInitialInstance
(
UpgradeTestCase
,
test_resiliency
.
TestTheiaResilienceWithInitialInstance
):
@
classmethod
def
beforeUpgrade
(
cls
):
# Check initial embedded instance
test
.
TestTheiaWithEmbeddedInstance
.
test
(
cls
())
class
TestResilientTheiaUpgradeWithInitialInstance
(
UpgradeTestCase
,
test_resiliency
.
ResilientTheiaTestCase
,
test_resiliency
.
TheiaSyncMixin
):
backup_max_tries
=
70
backup_wait_interval
=
10
old_flag_file
=
os
.
path
.
join
(
'etc'
,
'embedded-instance-config.json.done'
)
old_exitcode_file
=
os
.
path
.
join
(
'etc'
,
'embedded-request-exitcode'
)
flag_file
=
os
.
path
.
join
(
'var'
,
'state'
,
'standalone-ran-before.flag'
)
exitcode_file
=
os
.
path
.
join
(
'var'
,
'state'
,
'embedded-request.exitcode'
)
@
classmethod
def
getInstanceParameterDict
(
cls
):
return
{
'initial-embedded-instance'
:
json
.
dumps
({
'software-url'
:
test_resiliency
.
dummy_software_url
}),
}
def
assertExists
(
self
,
path
):
self
.
assertTrue
(
os
.
path
.
exists
(
path
))
def
assertNotFound
(
self
,
path
):
self
.
assertFalse
(
os
.
path
.
exists
(
path
))
@
classmethod
def
beforeUpgrade
(
cls
):
self
=
cls
()
self
.
assertExists
(
cls
.
getPartitionPath
(
'export'
,
self
.
old_flag_file
))
self
.
assertExists
(
cls
.
getPartitionPath
(
'export'
,
self
.
old_exitcode_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'import'
,
self
.
old_flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
old_exitcode_file
))
def
_prepareExport
(
self
):
# after upgrade
self
.
assertNotFound
(
self
.
getPartitionPath
(
'export'
,
self
.
old_flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'export'
,
self
.
old_exitcode_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
old_flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
old_exitcode_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'export'
,
self
.
flag_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'export'
,
self
.
exitcode_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'import'
,
self
.
flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
exitcode_file
))
def
_checkSync
(
self
):
self
.
assertExists
(
self
.
getPartitionPath
(
'export'
,
self
.
flag_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'export'
,
self
.
exitcode_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'import'
,
self
.
flag_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'import'
,
self
.
exitcode_file
))
def
_checkTakeover
(
self
):
self
.
assertNotFound
(
self
.
getPartitionPath
(
'export'
,
self
.
old_flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'export'
,
self
.
old_exitcode_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
old_flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
old_exitcode_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'export'
,
self
.
flag_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'export'
,
self
.
exitcode_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'import'
,
self
.
flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
exitcode_file
))
class
TestResilientTheiaUpgradeWithInitialInstanceAndSync
(
TestResilientTheiaUpgradeWithInitialInstance
):
@
classmethod
def
beforeUpgrade
(
cls
):
cls
().
_doSync
()
def
_prepareExport
(
self
):
# after upgrade
self
.
assertNotFound
(
self
.
getPartitionPath
(
'export'
,
self
.
old_flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'export'
,
self
.
old_exitcode_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
old_flag_file
))
self
.
assertNotFound
(
self
.
getPartitionPath
(
'import'
,
self
.
old_exitcode_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'export'
,
self
.
flag_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'export'
,
self
.
exitcode_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'import'
,
self
.
flag_file
))
self
.
assertExists
(
self
.
getPartitionPath
(
'import'
,
self
.
exitcode_file
))
stack/slapos.cfg
View file @
3fba7c6e
...
@@ -297,7 +297,7 @@ simplegeneric = 0.8.1
...
@@ -297,7 +297,7 @@ simplegeneric = 0.8.1
singledispatch = 3.4.0.3
singledispatch = 3.4.0.3
six = 1.16.0
six = 1.16.0
slapos.cookbook = 1.0.326
slapos.cookbook = 1.0.326
slapos.core = 1.10.
0
slapos.core = 1.10.
1
slapos.extension.shared = 1.0
slapos.extension.shared = 1.0
slapos.libnetworkcache = 0.25
slapos.libnetworkcache = 0.25
slapos.rebootstrap = 4.5
slapos.rebootstrap = 4.5
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment