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
Justin
slapos
Commits
e190bda9
Commit
e190bda9
authored
Feb 19, 2021
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Plain Diff
software/jupyter: fix parameters
See merge request
nexedi/slapos!892
parents
1b38f8df
1b4653ad
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
221 additions
and
37 deletions
+221
-37
software/jupyter/buildout.hash.cfg
software/jupyter/buildout.hash.cfg
+1
-1
software/jupyter/instance-jupyter-input-schema.json
software/jupyter/instance-jupyter-input-schema.json
+42
-0
software/jupyter/instance-jupyter-output-schema.json
software/jupyter/instance-jupyter-output-schema.json
+18
-0
software/jupyter/instance-jupyter.cfg.in
software/jupyter/instance-jupyter.cfg.in
+5
-1
software/jupyter/software.cfg.json
software/jupyter/software.cfg.json
+15
-0
software/jupyter/test/test.py
software/jupyter/test/test.py
+140
-35
No files found.
software/jupyter/buildout.hash.cfg
View file @
e190bda9
...
@@ -19,7 +19,7 @@ md5sum = de37ec3d4adb0be4c67bcc7397f27c91
...
@@ -19,7 +19,7 @@ md5sum = de37ec3d4adb0be4c67bcc7397f27c91
[instance-jupyter]
[instance-jupyter]
filename = instance-jupyter.cfg.in
filename = instance-jupyter.cfg.in
md5sum =
9340498841caa5771f40f8c9e561eacd
md5sum =
cbc90e517ae3680ab8bef04c6f503af5
[jupyter-notebook-config]
[jupyter-notebook-config]
filename = jupyter_notebook_config.py.jinja
filename = jupyter_notebook_config.py.jinja
...
...
software/jupyter/instance-jupyter-input-schema.json
0 → 100644
View file @
e190bda9
{
"$schema"
:
"http://json-schema.org/draft-04/schema#"
,
"description"
:
"Parameters to instantiate Jupyter"
,
"properties"
:
{
"frontend-instance-guid"
:
{
"title"
:
"Frontend Instance ID"
,
"description"
:
"Unique identifier of the frontend instance, like
\"
SOFTINST-11031
\"
."
,
"type"
:
"string"
},
"frontend-software-type"
:
{
"title"
:
"Frontend Software Type"
,
"description"
:
"Type of the frontend instance, like
\"
frontend
\"
."
,
"type"
:
"string"
,
"default"
:
"RootSoftwareInstance"
},
"frontend-software-url"
:
{
"title"
:
"Frontend Software URL"
,
"description"
:
"Software Release URL of the frontend instance, like
\"
http://example.com/path/to/software.cfg
\"
."
,
"type"
:
"string"
,
"format"
:
"uri"
,
"default"
:
"http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg"
},
"frontend-additional-instance-guid"
:
{
"title"
:
"Additional Frontend Instance ID"
,
"description"
:
"Unique identifier of the additional frontend instance, like
\"
SOFTINST-11031
\"
, if empty won't be requested."
,
"type"
:
"string"
},
"frontend-additional-software-type"
:
{
"title"
:
"Additional Frontend Software Type"
,
"description"
:
"Type of the frontend instance, like
\"
frontend
\"
."
,
"type"
:
"string"
,
"default"
:
"RootSoftwareInstance"
},
"frontend-additional-software-url"
:
{
"title"
:
"Additional Frontend Software URL"
,
"description"
:
"Software Release URL of the frontend instance, like
\"
http://example.com/path/to/software.cfg
\"
."
,
"type"
:
"string"
,
"format"
:
"uri"
,
"default"
:
"http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg"
}
}
}
software/jupyter/instance-jupyter-output-schema.json
0 → 100644
View file @
e190bda9
{
"$schema"
:
"http://json-schema.org/draft-04/schema#"
,
"description"
:
"Connection parameters for the Jupyter Notebook"
,
"properties"
:
{
"url"
:
{
"description"
:
"Jupyter Notebook URL"
,
"type"
:
"string"
},
"jupyterlab-url"
:
{
"description"
:
"JupyterLab URL"
,
"type"
:
"string"
},
"password"
:
{
"description"
:
"Password"
,
"type"
:
"string"
}
}
}
software/jupyter/instance-jupyter.cfg.in
View file @
e190bda9
...
@@ -51,6 +51,10 @@ frontend-additional-software-url = http://git.erp5.org/gitweb/slapos.git/blob_pl
...
@@ -51,6 +51,10 @@ frontend-additional-software-url = http://git.erp5.org/gitweb/slapos.git/blob_pl
frontend-additional-instance-guid =
frontend-additional-instance-guid =
frontend-additional-instance-name = Jupyter Frontend Additional
frontend-additional-instance-name = Jupyter Frontend Additional
{% for k, v in slapparameter_dict.items() -%}
{{ k }} = {{ v }}
{% endfor -%}
[dynamic-jinja2-template-base]
[dynamic-jinja2-template-base]
recipe = slapos.recipe.template:jinja2
recipe = slapos.recipe.template:jinja2
mode = 0644
mode = 0644
...
@@ -171,7 +175,7 @@ instance-configuration =
...
@@ -171,7 +175,7 @@ instance-configuration =
raw jupyter-password ${jupyter-password:passwd}
raw jupyter-password ${jupyter-password:passwd}
[publish-connection-parameter]
[publish-connection-parameter]
recipe = slapos.cookbook:publish
.serialised
recipe = slapos.cookbook:publish
jupyter-classic-url = ${request-slave-frontend:connection-secure_access}/tree
jupyter-classic-url = ${request-slave-frontend:connection-secure_access}/tree
url = ${:jupyter-classic-url}
url = ${:jupyter-classic-url}
jupyterlab-url = ${request-slave-frontend:connection-secure_access}/lab
jupyterlab-url = ${request-slave-frontend:connection-secure_access}/lab
...
...
software/jupyter/software.cfg.json
0 → 100644
View file @
e190bda9
{
"name"
:
"Jupyter"
,
"description"
:
"Jupyter Notebook"
,
"serialisation"
:
"json-in-xml"
,
"software-type"
:
{
"default"
:
{
"title"
:
"Default"
,
"software-type"
:
"default"
,
"description"
:
"Default"
,
"request"
:
"instance-jupyter-input-schema.json"
,
"response"
:
"instance-jupyter-ouput-schema.json"
,
"index"
:
1
}
}
}
software/jupyter/test/test.py
View file @
e190bda9
...
@@ -30,6 +30,8 @@ import http.client
...
@@ -30,6 +30,8 @@ import http.client
import
json
import
json
import
os
import
os
import
requests
import
requests
import
sqlite3
from
slapos.testing.testcase
import
makeModuleSetUpAndTestCaseClass
from
slapos.testing.testcase
import
makeModuleSetUpAndTestCaseClass
...
@@ -41,12 +43,7 @@ setUpModule, InstanceTestCase = makeModuleSetUpAndTestCaseClass(
...
@@ -41,12 +43,7 @@ setUpModule, InstanceTestCase = makeModuleSetUpAndTestCaseClass(
class
TestJupyter
(
InstanceTestCase
):
class
TestJupyter
(
InstanceTestCase
):
def
test
(
self
):
def
test
(
self
):
parameter_dict
=
self
.
computer_partition
.
getConnectionParameterDict
()
connection_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
))
self
.
assertTrue
(
'password'
in
connection_dict
)
self
.
assertTrue
(
'password'
in
connection_dict
)
password
=
connection_dict
[
'password'
]
password
=
connection_dict
[
'password'
]
...
@@ -85,29 +82,6 @@ class TestJupyter(InstanceTestCase):
...
@@ -85,29 +82,6 @@ class TestJupyter(InstanceTestCase):
)
)
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
):
class
TestJupyterAdditional
(
InstanceTestCase
):
@
classmethod
@
classmethod
...
@@ -117,12 +91,7 @@ class TestJupyterAdditional(InstanceTestCase):
...
@@ -117,12 +91,7 @@ class TestJupyterAdditional(InstanceTestCase):
}
}
def
test
(
self
):
def
test
(
self
):
parameter_dict
=
self
.
computer_partition
.
getConnectionParameterDict
()
connection_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
(
result
=
requests
.
get
(
connection_dict
[
'url'
],
verify
=
False
,
allow_redirects
=
False
)
connection_dict
[
'url'
],
verify
=
False
,
allow_redirects
=
False
)
...
@@ -169,3 +138,139 @@ class TestJupyterAdditional(InstanceTestCase):
...
@@ -169,3 +138,139 @@ class TestJupyterAdditional(InstanceTestCase):
[
http
.
client
.
FOUND
,
True
,
'/login?next=%2Flab'
],
[
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'
]]
)
)
class
TestJupyterPassword
(
InstanceTestCase
):
def
test
(
self
):
connection_dict
=
self
.
computer_partition
.
getConnectionParameterDict
()
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
SelectMixin
(
object
):
def
sqlite3_connect
(
self
):
sqlitedb_file
=
os
.
path
.
join
(
os
.
path
.
abspath
(
os
.
path
.
join
(
self
.
slap
.
instance_directory
,
os
.
pardir
)
),
'var'
,
'proxy.db'
)
return
sqlite3
.
connect
(
sqlitedb_file
)
def
select
(
self
,
fields
,
table
,
where
=
{}):
connection
=
self
.
sqlite3_connect
()
def
dict_factory
(
cursor
,
row
):
d
=
{}
for
idx
,
col
in
enumerate
(
cursor
.
description
):
d
[
col
[
0
]]
=
row
[
idx
]
return
d
connection
.
row_factory
=
dict_factory
cursor
=
connection
.
cursor
()
condition
=
" AND "
.
join
(
"%s='%s'"
%
(
k
,
v
)
for
k
,
v
in
where
.
items
())
cursor
.
execute
(
"SELECT %s FROM %s%s"
%
(
", "
.
join
(
fields
),
table
,
" WHERE %s"
%
condition
if
where
else
""
,
)
)
return
cursor
.
fetchall
()
class
TestJupyterCustomFrontend
(
SelectMixin
,
InstanceTestCase
):
instance_parameter_dict
=
{}
frontend_software_url
=
'hello://frontend.url'
frontend_software_type
=
'hello-type'
frontend_instance_name
=
'Hello Frontend'
@
classmethod
def
getInstanceParameterDict
(
cls
):
return
cls
.
instance_parameter_dict
def
test
(
self
):
# create a fake master instance for the frontend slave request
r
=
self
.
slap
.
request
(
software_release
=
self
.
frontend_software_url
,
software_type
=
self
.
frontend_software_type
,
partition_reference
=
"Fake master instance"
,
)
# update the request parameters of the test instance
self
.
instance_parameter_dict
.
update
({
'frontend-software-url'
:
self
.
frontend_software_url
,
'frontend-software-type'
:
self
.
frontend_software_type
,
'frontend-instance-name'
:
self
.
frontend_instance_name
,
'frontend-instance-guid'
:
r
.
_partition_id
,
})
self
.
requestDefaultInstance
()
# wait for the instance to converge to the new state
try
:
self
.
slap
.
waitForInstance
()
except
Exception
:
pass
selection
=
self
.
select
(
fields
=
[
"*"
],
table
=
"slave14"
,
where
=
{
"hosted_by"
:
r
.
_partition_id
})
self
.
assertEqual
(
len
(
selection
),
1
)
# clean up the fake master
r
.
destroyed
()
class
TestJupyterCustomAdditional
(
SelectMixin
,
InstanceTestCase
):
instance_parameter_dict
=
{}
frontend_additional_software_url
=
'hello://frontend.url'
frontend_additional_software_type
=
'hello-type'
frontend_additional_instance_name
=
'Hello Frontend'
@
classmethod
def
getInstanceParameterDict
(
cls
):
return
cls
.
instance_parameter_dict
def
test
(
self
):
# create a fake master instance for the frontend slave request
r
=
self
.
slap
.
request
(
software_release
=
self
.
frontend_additional_software_url
,
software_type
=
self
.
frontend_additional_software_type
,
partition_reference
=
"Fake master instance"
,
)
# update the request parameters of the test instance
self
.
instance_parameter_dict
.
update
({
'frontend-additional-software-url'
:
self
.
frontend_additional_software_url
,
'frontend-additional-software-type'
:
self
.
frontend_additional_software_type
,
'frontend-additional-instance-name'
:
self
.
frontend_additional_instance_name
,
'frontend-additional-instance-guid'
:
r
.
_partition_id
,
})
self
.
requestDefaultInstance
()
# wait for the instance to converge to the new state
try
:
self
.
slap
.
waitForInstance
()
except
Exception
:
pass
selection
=
self
.
select
(
fields
=
[
"*"
],
table
=
"slave14"
,
where
=
{
"hosted_by"
:
r
.
_partition_id
})
self
.
assertEqual
(
len
(
selection
),
1
)
# clean up the fake master
r
.
destroyed
()
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