Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
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
Jérome Perrin
slapos.core
Commits
656a5721
Commit
656a5721
authored
May 11, 2020
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP type defintions
parent
34d7fb60
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
165 additions
and
39 deletions
+165
-39
mypy.ini
mypy.ini
+17
-0
setup.py
setup.py
+2
-1
slapos/__init__.py
slapos/__init__.py
+1
-1
slapos/cli/proxy_show.py
slapos/cli/proxy_show.py
+1
-1
slapos/collect/temperature/__init__.py
slapos/collect/temperature/__init__.py
+7
-3
slapos/grid/SlapObject.py
slapos/grid/SlapObject.py
+2
-1
slapos/grid/slapgrid.py
slapos/grid/slapgrid.py
+14
-8
slapos/grid/svcbackend.py
slapos/grid/svcbackend.py
+1
-1
slapos/proxy/views.py
slapos/proxy/views.py
+10
-4
slapos/slap/slap.py
slapos/slap/slap.py
+57
-6
slapos/slap/standalone.py
slapos/slap/standalone.py
+41
-7
slapos/tests/test_prune.py
slapos/tests/test_prune.py
+4
-3
slapos/tests/test_slapproxy.py
slapos/tests/test_slapproxy.py
+8
-3
No files found.
mypy.ini
0 → 100644
View file @
656a5721
[mypy]
ignore_missing_imports
=
True
[mypy-slapos]
ignore_missing_imports
=
True
[mypy-slapos.slap]
ignore_missing_imports
=
True
[mypy-slapos.slap.grid]
ignore_missing_imports
=
True
# interfaces cause error: Method must have at least one argument
[mypy-slapos.slap.interface]
ignore_errors
=
True
[mypy-slapos.slap.interface.slap]
ignore_errors
=
True
setup.py
View file @
656a5721
...
@@ -75,7 +75,8 @@ setup(name=name,
...
@@ -75,7 +75,8 @@ setup(name=name,
'cachecontrol'
,
'cachecontrol'
,
'lockfile'
,
'lockfile'
,
'uritemplate'
,
# used by hateoas navigator
'uritemplate'
,
# used by hateoas navigator
'subprocess32; python_version<"3"'
'subprocess32; python_version<"3"'
,
'typing; python_version<"3"'
,
]
+
additional_install_requires
,
]
+
additional_install_requires
,
extras_require
=
extras_require
,
extras_require
=
extras_require
,
tests_require
=
extras_require
[
'test'
],
tests_require
=
extras_require
[
'test'
],
...
...
slapos/__init__.py
View file @
656a5721
...
@@ -3,4 +3,4 @@ try:
...
@@ -3,4 +3,4 @@ try:
__import__
(
'pkg_resources'
).
declare_namespace
(
__name__
)
__import__
(
'pkg_resources'
).
declare_namespace
(
__name__
)
except
ImportError
:
except
ImportError
:
from
pkgutil
import
extend_path
from
pkgutil
import
extend_path
__path__
=
extend_path
(
__path__
,
__name__
)
__path__
=
extend_path
(
__path__
,
__name__
)
# type: ignore
slapos/cli/proxy_show.py
View file @
656a5721
...
@@ -44,7 +44,7 @@ from slapos.proxy import ProxyConfig
...
@@ -44,7 +44,7 @@ from slapos.proxy import ProxyConfig
from
slapos.proxy.db_version
import
DB_VERSION
from
slapos.proxy.db_version
import
DB_VERSION
from
slapos.util
import
sqlite_connect
,
str2bytes
from
slapos.util
import
sqlite_connect
,
str2bytes
if
bytes
is
str
:
if
sys
.
version_info
[
0
]
==
3
:
from
io
import
BytesIO
from
io
import
BytesIO
class
StringIO
(
BytesIO
):
class
StringIO
(
BytesIO
):
# Something between strict io.BytesIO and laxist/slow StringIO.StringIO
# Something between strict io.BytesIO and laxist/slow StringIO.StringIO
...
...
slapos/collect/temperature/__init__.py
View file @
656a5721
from
__future__
import
print_function
from
__future__
import
print_function
from
multiprocessing
import
Process
,
active_children
,
cpu_count
,
Pipe
from
multiprocessing
import
Process
,
active_children
,
cpu_count
,
Pipe
try
:
from
typing
import
TYPE_CHECKING
import
subprocess32
as
subprocess
if
TYPE_CHECKING
:
except
ImportError
:
import
subprocess
import
subprocess
else
:
try
:
import
subprocess32
as
subprocess
except
ImportError
:
import
subprocess
import
os
import
os
import
signal
import
signal
import
sys
import
sys
...
...
slapos/grid/SlapObject.py
View file @
656a5721
...
@@ -38,7 +38,8 @@ import subprocess
...
@@ -38,7 +38,8 @@ import subprocess
import
tarfile
import
tarfile
import
tempfile
import
tempfile
import
time
import
time
from
six.moves
import
xmlrpc_client
as
xmlrpclib
,
range
from
six.moves
import
xmlrpc_client
as
xmlrpclib
# type: ignore
from
six.moves
import
range
from
six.moves.configparser
import
ConfigParser
from
six.moves.configparser
import
ConfigParser
from
supervisor
import
xmlrpc
from
supervisor
import
xmlrpc
...
...
slapos/grid/slapgrid.py
View file @
656a5721
...
@@ -49,6 +49,10 @@ if sys.version_info < (2, 6):
...
@@ -49,6 +49,10 @@ if sys.version_info < (2, 6):
warnings
.
warn
(
'Used python version (%s) is old and has problems with'
warnings
.
warn
(
'Used python version (%s) is old and has problems with'
' IPv6 connections'
%
sys
.
version
.
split
(
'
\
n
'
)[
0
])
' IPv6 connections'
%
sys
.
version
.
split
(
'
\
n
'
)[
0
])
from
typing
import
List
,
Tuple
,
Sequence
,
TYPE_CHECKING
if
TYPE_CHECKING
:
from
..slap.slap
import
ComputerPartition
from
lxml
import
etree
from
lxml
import
etree
from
slapos
import
manager
as
slapmanager
from
slapos
import
manager
as
slapmanager
...
@@ -537,6 +541,7 @@ stderr_logfile_backups=1
...
@@ -537,6 +541,7 @@ stderr_logfile_backups=1
launchSupervisord
(
instance_root
=
self
.
instance_root
,
logger
=
self
.
logger
)
launchSupervisord
(
instance_root
=
self
.
instance_root
,
logger
=
self
.
logger
)
def
getComputerPartitionList
(
self
):
def
getComputerPartitionList
(
self
):
# type: () -> Sequence[ComputerPartition]
try
:
try
:
return
self
.
computer
.
getComputerPartitionList
()
return
self
.
computer
.
getComputerPartitionList
()
except
socket
.
error
as
exc
:
except
socket
.
error
as
exc
:
...
@@ -789,7 +794,7 @@ stderr_logfile_backups=1
...
@@ -789,7 +794,7 @@ stderr_logfile_backups=1
reload_process
=
FPopen
(
reload_cmd
,
universal_newlines
=
True
)
reload_process
=
FPopen
(
reload_cmd
,
universal_newlines
=
True
)
stdout
,
stderr
=
reload_process
.
communicate
()
stdout
,
stderr
=
reload_process
.
communicate
()
if
reload_process
.
returncode
!=
0
:
if
reload_process
.
returncode
!=
0
:
raise
Exception
(
"Failed to load firewalld rules with command %s.
\
n
%"
%
(
raise
Exception
(
"Failed to load firewalld rules with command %s.
\
n
%
s
"
%
(
stderr
,
reload_cmd
))
stderr
,
reload_cmd
))
with
open
(
firewall_rules_path
,
'w'
)
as
frules
:
with
open
(
firewall_rules_path
,
'w'
)
as
frules
:
...
@@ -1254,6 +1259,7 @@ stderr_logfile_backups=1
...
@@ -1254,6 +1259,7 @@ stderr_logfile_backups=1
f
.
write
(
str
(
timestamp
))
f
.
write
(
str
(
timestamp
))
def
FilterComputerPartitionList
(
self
,
computer_partition_list
):
def
FilterComputerPartitionList
(
self
,
computer_partition_list
):
# type: (Sequence[ComputerPartition]) -> List[ComputerPartition]
"""
"""
Try to filter valid partitions to be processed from free partitions.
Try to filter valid partitions to be processed from free partitions.
"""
"""
...
@@ -1392,12 +1398,12 @@ stderr_logfile_backups=1
...
@@ -1392,12 +1398,12 @@ stderr_logfile_backups=1
self
.
logger
.
info
(
'='
*
80
)
self
.
logger
.
info
(
'='
*
80
)
if
process_error_partition_list
:
if
process_error_partition_list
:
self
.
logger
.
info
(
'Error while processing the following partitions:'
)
self
.
logger
.
info
(
'Error while processing the following partitions:'
)
for
partition
,
e
xc
in
process_error_partition_list
:
for
partition
,
e
rror
in
process_error_partition_list
:
self
.
logger
.
info
(
' %s[%s]: %s'
,
partition
.
getId
(),
getPartitionType
(
partition
),
e
xc
)
self
.
logger
.
info
(
' %s[%s]: %s'
,
partition
.
getId
(),
getPartitionType
(
partition
),
e
rror
)
if
promise_error_partition_list
:
if
promise_error_partition_list
:
self
.
logger
.
info
(
'Error with promises for the following partitions:'
)
self
.
logger
.
info
(
'Error with promises for the following partitions:'
)
for
partition
,
e
xc
in
promise_error_partition_list
:
for
partition
,
e
rror
in
promise_error_partition_list
:
self
.
logger
.
info
(
' %s[%s]: %s'
,
partition
.
getId
(),
getPartitionType
(
partition
),
e
xc
)
self
.
logger
.
info
(
' %s[%s]: %s'
,
partition
.
getId
(),
getPartitionType
(
partition
),
e
rror
)
# Return success value
# Return success value
if
not
clean_run
:
if
not
clean_run
:
...
@@ -1420,7 +1426,7 @@ stderr_logfile_backups=1
...
@@ -1420,7 +1426,7 @@ stderr_logfile_backups=1
computer_partition_list
=
self
.
FilterComputerPartitionList
(
computer_partition_list
=
self
.
FilterComputerPartitionList
(
self
.
getComputerPartitionList
())
self
.
getComputerPartitionList
())
promise_error_partition_list
=
[]
promise_error_partition_list
=
[]
# type: List[Tuple[ComputerPartition, Union[PromiseError, Exception]]]
for
computer_partition
in
computer_partition_list
:
for
computer_partition
in
computer_partition_list
:
try
:
try
:
# Process the partition itself
# Process the partition itself
...
@@ -1444,8 +1450,8 @@ stderr_logfile_backups=1
...
@@ -1444,8 +1450,8 @@ stderr_logfile_backups=1
if
promise_error_partition_list
:
if
promise_error_partition_list
:
self
.
logger
.
info
(
'Finished computer partitions.'
)
self
.
logger
.
info
(
'Finished computer partitions.'
)
for
partition
,
e
xc
in
promise_error_partition_list
:
for
partition
,
e
rror
in
promise_error_partition_list
:
self
.
logger
.
info
(
' %s[%s]: %s'
,
partition
.
getId
(),
getPartitionType
(
partition
),
e
xc
)
self
.
logger
.
info
(
' %s[%s]: %s'
,
partition
.
getId
(),
getPartitionType
(
partition
),
e
rror
)
# Return success value
# Return success value
if
not
clean_run_promise
:
if
not
clean_run_promise
:
...
...
slapos/grid/svcbackend.py
View file @
656a5721
...
@@ -35,7 +35,7 @@ import subprocess
...
@@ -35,7 +35,7 @@ import subprocess
import
stat
import
stat
import
sys
import
sys
import
time
import
time
from
six.moves
import
xmlrpc_client
as
xmlrpclib
from
six.moves
import
xmlrpc_client
as
xmlrpclib
# type: ignore
import
contextlib
import
contextlib
from
slapos.grid.utils
import
(
createPrivateDirectory
,
SlapPopen
,
updateFile
)
from
slapos.grid.utils
import
(
createPrivateDirectory
,
SlapPopen
,
updateFile
)
...
...
slapos/proxy/views.py
View file @
656a5721
...
@@ -53,8 +53,11 @@ EMPTY_DICT_XML = dumps({})
...
@@ -53,8 +53,11 @@ EMPTY_DICT_XML = dumps({})
class
UnauthorizedError
(
Exception
):
class
UnauthorizedError
(
Exception
):
pass
pass
from
typing
import
Dict
,
Union
,
no_type_check
@
no_type_check
def
partitiondict2partition
(
partition
):
def
partitiondict2partition
(
partition
):
# type: (Dict[str, str]) -> ComputerPartition
slap_partition
=
ComputerPartition
(
partition
[
'computer_reference'
],
slap_partition
=
ComputerPartition
(
partition
[
'computer_reference'
],
partition
[
'reference'
])
partition
[
'reference'
])
slap_partition
.
_software_release_document
=
None
slap_partition
.
_software_release_document
=
None
...
@@ -365,6 +368,7 @@ def supplySupply():
...
@@ -365,6 +368,7 @@ def supplySupply():
@
app
.
route
(
'/requestComputerPartition'
,
methods
=
[
'POST'
])
@
app
.
route
(
'/requestComputerPartition'
,
methods
=
[
'POST'
])
def
requestComputerPartition
():
def
requestComputerPartition
():
# type: () -> str
parsed_request_dict
=
parseRequestComputerPartitionForm
(
request
.
form
)
parsed_request_dict
=
parseRequestComputerPartitionForm
(
request
.
form
)
# Is it a slave instance?
# Is it a slave instance?
slave
=
loads
(
request
.
form
.
get
(
'shared_xml'
,
EMPTY_DICT_XML
).
encode
(
'utf-8'
))
slave
=
loads
(
request
.
form
.
get
(
'shared_xml'
,
EMPTY_DICT_XML
).
encode
(
'utf-8'
))
...
@@ -457,6 +461,7 @@ def requestComputerPartition():
...
@@ -457,6 +461,7 @@ def requestComputerPartition():
return
dumps
(
software_instance
)
return
dumps
(
software_instance
)
def
parseRequestComputerPartitionForm
(
form
):
def
parseRequestComputerPartitionForm
(
form
):
# type: (Dict) -> Dict
"""
"""
Parse without intelligence a form from a request(), return it.
Parse without intelligence a form from a request(), return it.
"""
"""
...
@@ -469,7 +474,7 @@ def parseRequestComputerPartitionForm(form):
...
@@ -469,7 +474,7 @@ def parseRequestComputerPartitionForm(form):
'filter_kw'
:
loads
(
form
.
get
(
'filter_xml'
,
EMPTY_DICT_XML
).
encode
(
'utf-8'
)),
'filter_kw'
:
loads
(
form
.
get
(
'filter_xml'
,
EMPTY_DICT_XML
).
encode
(
'utf-8'
)),
# Note: currently ignored for slave instance (slave instances
# Note: currently ignored for slave instance (slave instances
# are always started).
# are always started).
'requested_state'
:
loads
(
form
.
get
(
'state'
)
.
encode
(
'utf-8'
)),
'requested_state'
:
loads
(
form
[
'state'
]
.
encode
(
'utf-8'
)),
}
}
return
parsed_dict
return
parsed_dict
...
@@ -543,10 +548,11 @@ def isRequestToBeForwardedToExternalMaster(parsed_request_dict):
...
@@ -543,10 +548,11 @@ def isRequestToBeForwardedToExternalMaster(parsed_request_dict):
return
None
return
None
def
forwardRequestToExternalMaster
(
master_url
,
request_form
):
def
forwardRequestToExternalMaster
(
master_url
,
request_form
):
# type: (str, Dict) -> str
"""
"""
Forward instance request to external SlapOS Master.
Forward instance request to external SlapOS Master.
"""
"""
master_entry
=
app
.
config
.
get
(
'multimaster'
)
.
get
(
master_url
,
{})
master_entry
=
app
.
config
[
'multimaster'
]
.
get
(
master_url
,
{})
key_file
=
master_entry
.
get
(
'key'
)
key_file
=
master_entry
.
get
(
'key'
)
cert_file
=
master_entry
.
get
(
'cert'
)
cert_file
=
master_entry
.
get
(
'cert'
)
if
master_url
.
startswith
(
'https'
)
and
(
not
key_file
or
not
cert_file
):
if
master_url
.
startswith
(
'https'
)
and
(
not
key_file
or
not
cert_file
):
...
@@ -568,7 +574,7 @@ def forwardRequestToExternalMaster(master_url, request_form):
...
@@ -568,7 +574,7 @@ def forwardRequestToExternalMaster(master_url, request_form):
{
'partition_reference'
:
partition_reference
,
'master_url'
:
master_url
})
{
'partition_reference'
:
partition_reference
,
'master_url'
:
master_url
})
new_request_form
=
request_form
.
copy
()
new_request_form
=
request_form
.
copy
()
filter_kw
=
loads
(
new_
request_form
[
'filter_xml'
].
encode
(
'utf-8'
))
filter_kw
=
loads
(
request_form
[
'filter_xml'
].
encode
(
'utf-8'
))
filter_kw
[
'source_instance_id'
]
=
partition_reference
filter_kw
[
'source_instance_id'
]
=
partition_reference
new_request_form
[
'filter_xml'
]
=
dumps
(
filter_kw
)
new_request_form
[
'filter_xml'
]
=
dumps
(
filter_kw
)
...
@@ -576,7 +582,7 @@ def forwardRequestToExternalMaster(master_url, request_form):
...
@@ -576,7 +582,7 @@ def forwardRequestToExternalMaster(master_url, request_form):
partition
=
loads
(
xml
)
partition
=
loads
(
xml
)
# XXX move to other end
# XXX move to other end
partition
.
_master_url
=
master_url
partition
.
_master_url
=
master_url
# type: ignore
return
dumps
(
partition
)
return
dumps
(
partition
)
...
...
slapos/slap/slap.py
View file @
656a5721
This diff is collapsed.
Click to expand it.
slapos/slap/standalone.py
View file @
656a5721
...
@@ -38,10 +38,16 @@ import shutil
...
@@ -38,10 +38,16 @@ import shutil
from
six.moves
import
urllib
from
six.moves
import
urllib
from
six.moves
import
http_client
from
six.moves
import
http_client
try
:
from
typing
import
TYPE_CHECKING
,
Optional
,
Iterable
,
Dict
import
subprocess32
as
subprocess
if
TYPE_CHECKING
:
except
ImportError
:
import
subprocess
import
subprocess
from
..slap.slap
import
Computer
,
ComputerPartition
,
SoftwareState
,
InstanceState
,
PartitionParameters
,
FilterParameters
else
:
try
:
import
subprocess32
as
subprocess
except
ImportError
:
import
subprocess
import
xml_marshaller
import
xml_marshaller
import
zope.interface
import
zope.interface
...
@@ -80,9 +86,11 @@ class ConfigWriter(object):
...
@@ -80,9 +86,11 @@ class ConfigWriter(object):
"""Base class for an object writing a config file or wrapper script.
"""Base class for an object writing a config file or wrapper script.
"""
"""
def
__init__
(
self
,
standalone_slapos
):
def
__init__
(
self
,
standalone_slapos
):
# type: (StandaloneSlapOS) -> None
self
.
_standalone_slapos
=
standalone_slapos
self
.
_standalone_slapos
=
standalone_slapos
def
writeConfig
(
self
,
path
):
def
writeConfig
(
self
,
path
):
# type: (str) -> None
NotImplemented
NotImplemented
...
@@ -90,6 +98,7 @@ class SupervisorConfigWriter(ConfigWriter):
...
@@ -90,6 +98,7 @@ class SupervisorConfigWriter(ConfigWriter):
"""Write supervisor configuration at etc/supervisor.conf
"""Write supervisor configuration at etc/supervisor.conf
"""
"""
def
_getProgramConfig
(
self
,
program_name
,
command
,
stdout_logfile
):
def
_getProgramConfig
(
self
,
program_name
,
command
,
stdout_logfile
):
# type: (str, str, str) -> str
"""Format a supervisor program block.
"""Format a supervisor program block.
"""
"""
return
textwrap
.
dedent
(
return
textwrap
.
dedent
(
...
@@ -108,6 +117,7 @@ class SupervisorConfigWriter(ConfigWriter):
...
@@ -108,6 +117,7 @@ class SupervisorConfigWriter(ConfigWriter):
"""
).
format
(
**
locals
())
"""
).
format
(
**
locals
())
def
_getSupervisorConfigParts
(
self
):
def
_getSupervisorConfigParts
(
self
):
# type: () -> Iterable[str]
"""Iterator on parts of formatted config.
"""Iterator on parts of formatted config.
"""
"""
standalone_slapos
=
self
.
_standalone_slapos
standalone_slapos
=
self
.
_standalone_slapos
...
@@ -143,6 +153,7 @@ class SupervisorConfigWriter(ConfigWriter):
...
@@ -143,6 +153,7 @@ class SupervisorConfigWriter(ConfigWriter):
'stdout_logfile'
,
'AUTO'
).
format
(
self
=
standalone_slapos
))
'stdout_logfile'
,
'AUTO'
).
format
(
self
=
standalone_slapos
))
def
writeConfig
(
self
,
path
):
def
writeConfig
(
self
,
path
):
# type: (str) -> None
with
open
(
path
,
'w'
)
as
f
:
with
open
(
path
,
'w'
)
as
f
:
for
part
in
self
.
_getSupervisorConfigParts
():
for
part
in
self
.
_getSupervisorConfigParts
():
f
.
write
(
part
)
f
.
write
(
part
)
...
@@ -151,8 +162,10 @@ class SupervisorConfigWriter(ConfigWriter):
...
@@ -151,8 +162,10 @@ class SupervisorConfigWriter(ConfigWriter):
class
SlapOSConfigWriter
(
ConfigWriter
):
class
SlapOSConfigWriter
(
ConfigWriter
):
"""Write slapos configuration at etc/slapos.cfg
"""Write slapos configuration at etc/slapos.cfg
"""
"""
def
writeConfig
(
self
,
path
):
def
writeConfig
(
self
,
path
):
standalone_slapos
=
self
.
_standalone_slapos
# type: StandaloneSlapOS
# type: (str) -> None
standalone_slapos
=
self
.
_standalone_slapos
read_only_shared_part_list
=
'
\
n
'
.
join
(
# pylint: disable=unused-variable; used in format()
read_only_shared_part_list
=
'
\
n
'
.
join
(
# pylint: disable=unused-variable; used in format()
standalone_slapos
.
_shared_part_list
)
standalone_slapos
.
_shared_part_list
)
with
open
(
path
,
'w'
)
as
f
:
with
open
(
path
,
'w'
)
as
f
:
...
@@ -183,6 +196,7 @@ class SlapOSCommandWriter(ConfigWriter):
...
@@ -183,6 +196,7 @@ class SlapOSCommandWriter(ConfigWriter):
"""Write a bin/slapos wrapper.
"""Write a bin/slapos wrapper.
"""
"""
def
writeConfig
(
self
,
path
):
def
writeConfig
(
self
,
path
):
# type: (str) -> None
with
open
(
path
,
'w'
)
as
f
:
with
open
(
path
,
'w'
)
as
f
:
f
.
write
(
f
.
write
(
textwrap
.
dedent
(
textwrap
.
dedent
(
...
@@ -215,7 +229,9 @@ class StandaloneSlapOS(object):
...
@@ -215,7 +229,9 @@ class StandaloneSlapOS(object):
shared_part_list
=
(),
shared_part_list
=
(),
software_root
=
None
,
software_root
=
None
,
instance_root
=
None
,
instance_root
=
None
,
shared_part_root
=
None
):
shared_part_root
=
None
,
):
# type: (str, str, int, str, Iterable[str], Optional[str], Optional[str], Optional[str]) -> None
"""Constructor, creates a standalone slapos in `base_directory`.
"""Constructor, creates a standalone slapos in `base_directory`.
Arguments:
Arguments:
...
@@ -273,6 +289,7 @@ class StandaloneSlapOS(object):
...
@@ -273,6 +289,7 @@ class StandaloneSlapOS(object):
self
.
_initBaseDirectory
(
software_root
,
instance_root
,
shared_part_root
)
self
.
_initBaseDirectory
(
software_root
,
instance_root
,
shared_part_root
)
def
_initBaseDirectory
(
self
,
software_root
,
instance_root
,
shared_part_root
):
def
_initBaseDirectory
(
self
,
software_root
,
instance_root
,
shared_part_root
):
# type: (Optional[str], Optional[str], Optional[str]) -> None
"""Create the directory after checking it's not too deep.
"""Create the directory after checking it's not too deep.
"""
"""
base_directory
=
self
.
_base_directory
base_directory
=
self
.
_base_directory
...
@@ -337,6 +354,7 @@ class StandaloneSlapOS(object):
...
@@ -337,6 +354,7 @@ class StandaloneSlapOS(object):
@
property
@
property
def
computer
(
self
):
def
computer
(
self
):
# type: () -> Computer
"""Access the computer.
"""Access the computer.
"""
"""
return
self
.
_slap
.
registerComputer
(
self
.
_computer_id
)
return
self
.
_slap
.
registerComputer
(
self
.
_computer_id
)
...
@@ -391,6 +409,7 @@ class StandaloneSlapOS(object):
...
@@ -391,6 +409,7 @@ class StandaloneSlapOS(object):
ipv4_address
,
ipv4_address
,
ipv6_address
,
ipv6_address
,
partition_base_name
=
"slappart"
):
partition_base_name
=
"slappart"
):
# type: (int, str, str, str) -> None
"""Creates `partition_count` partitions.
"""Creates `partition_count` partitions.
All partitions have the same `ipv4_address` and `ipv6_address` and
All partitions have the same `ipv4_address` and `ipv6_address` and
...
@@ -489,6 +508,7 @@ class StandaloneSlapOS(object):
...
@@ -489,6 +508,7 @@ class StandaloneSlapOS(object):
os
.
unlink
(
supervisor_conf
)
os
.
unlink
(
supervisor_conf
)
def
supply
(
self
,
software_url
,
computer_guid
=
None
,
state
=
"available"
):
def
supply
(
self
,
software_url
,
computer_guid
=
None
,
state
=
"available"
):
# type: (str, Optional[str], SoftwareState) -> None
"""Supply a software, see ISupply.supply
"""Supply a software, see ISupply.supply
Software can only be supplied on this embedded computer.
Software can only be supplied on this embedded computer.
...
@@ -510,6 +530,7 @@ class StandaloneSlapOS(object):
...
@@ -510,6 +530,7 @@ class StandaloneSlapOS(object):
partition_parameter_kw
=
None
,
partition_parameter_kw
=
None
,
filter_kw
=
None
,
filter_kw
=
None
,
state
=
None
):
state
=
None
):
# type: (str, str, Optional[str], bool, Optional[PartitionParameters], Optional[FilterParameters], Optional[InstanceState]) -> ComputerPartition
"""Request an instance, see IRequester.request
"""Request an instance, see IRequester.request
Instance can only be requested on this embedded computer.
Instance can only be requested on this embedded computer.
...
@@ -526,6 +547,7 @@ class StandaloneSlapOS(object):
...
@@ -526,6 +547,7 @@ class StandaloneSlapOS(object):
state
=
state
)
state
=
state
)
def
start
(
self
):
def
start
(
self
):
# type: () -> None
"""Start the system.
"""Start the system.
If system was stopped, it will start partitions.
If system was stopped, it will start partitions.
...
@@ -536,6 +558,7 @@ class StandaloneSlapOS(object):
...
@@ -536,6 +558,7 @@ class StandaloneSlapOS(object):
self
.
_ensureSlapOSAvailable
()
self
.
_ensureSlapOSAvailable
()
def
stop
(
self
):
def
stop
(
self
):
# type: () -> None
"""Stops all services.
"""Stops all services.
This methods blocks until services are stopped or a timeout is reached.
This methods blocks until services are stopped or a timeout is reached.
...
@@ -573,6 +596,7 @@ class StandaloneSlapOS(object):
...
@@ -573,6 +596,7 @@ class StandaloneSlapOS(object):
alive
+
instance_process_alive
))
alive
+
instance_process_alive
))
def
waitForSoftware
(
self
,
max_retry
=
0
,
debug
=
False
,
error_lines
=
30
):
def
waitForSoftware
(
self
,
max_retry
=
0
,
debug
=
False
,
error_lines
=
30
):
# type: (int, bool, int) -> None
"""Synchronously install or uninstall all softwares previously supplied/removed.
"""Synchronously install or uninstall all softwares previously supplied/removed.
This method retries on errors. If after `max_retry` times there's
This method retries on errors. If after `max_retry` times there's
...
@@ -594,6 +618,7 @@ class StandaloneSlapOS(object):
...
@@ -594,6 +618,7 @@ class StandaloneSlapOS(object):
)
)
def
waitForInstance
(
self
,
max_retry
=
0
,
debug
=
False
,
error_lines
=
30
):
def
waitForInstance
(
self
,
max_retry
=
0
,
debug
=
False
,
error_lines
=
30
):
# type: (int, bool, int) -> None
"""Instantiate all partitions previously requested for start.
"""Instantiate all partitions previously requested for start.
This method retries on errors. If after `max_retry` times there's
This method retries on errors. If after `max_retry` times there's
...
@@ -615,6 +640,7 @@ class StandaloneSlapOS(object):
...
@@ -615,6 +640,7 @@ class StandaloneSlapOS(object):
)
)
def
waitForReport
(
self
,
max_retry
=
0
,
debug
=
False
,
error_lines
=
30
):
def
waitForReport
(
self
,
max_retry
=
0
,
debug
=
False
,
error_lines
=
30
):
# type: (int, bool, int) -> None
"""Destroy all partitions previously requested for destruction.
"""Destroy all partitions previously requested for destruction.
This method retries on errors. If after `max_retry` times there's
This method retries on errors. If after `max_retry` times there's
...
@@ -637,17 +663,19 @@ class StandaloneSlapOS(object):
...
@@ -637,17 +663,19 @@ class StandaloneSlapOS(object):
def
_runSlapOSCommand
(
def
_runSlapOSCommand
(
self
,
command
,
max_retry
=
0
,
debug
=
False
,
error_lines
=
30
):
self
,
command
,
max_retry
=
0
,
debug
=
False
,
error_lines
=
30
):
# type: (str, int, bool, int) -> None
if
debug
:
if
debug
:
prog
=
self
.
_slapos_commands
[
command
]
prog
=
self
.
_slapos_commands
[
command
]
# used in format(**locals()) below
# used in format(**locals()) below
debug_args
=
prog
.
get
(
'debug_args'
,
''
)
# pylint: disable=unused-variable
debug_args
=
prog
.
get
(
'debug_args'
,
''
)
# pylint: disable=unused-variable
command
=
prog
[
'command'
].
format
(
**
locals
())
command
=
prog
[
'command'
].
format
(
**
locals
())
try
:
try
:
return
subprocess
.
check_call
(
subprocess
.
check_call
(
command
,
command
,
shell
=
True
,
shell
=
True
,
env
=
self
.
_getSubprocessEnvironment
(),
env
=
self
.
_getSubprocessEnvironment
(),
)
)
return
except
subprocess
.
CalledProcessError
as
e
:
except
subprocess
.
CalledProcessError
as
e
:
if
e
.
returncode
==
SLAPGRID_PROMISE_FAIL
:
if
e
.
returncode
==
SLAPGRID_PROMISE_FAIL
:
self
.
_logger
.
exception
(
'Promise error when running %s'
,
command
)
self
.
_logger
.
exception
(
'Promise error when running %s'
,
command
)
...
@@ -687,6 +715,7 @@ class StandaloneSlapOS(object):
...
@@ -687,6 +715,7 @@ class StandaloneSlapOS(object):
retry
+=
1
retry
+=
1
def
_ensureSupervisordStarted
(
self
):
def
_ensureSupervisordStarted
(
self
):
# type: () -> None
if
os
.
path
.
exists
(
self
.
_supervisor_pid
):
if
os
.
path
.
exists
(
self
.
_supervisor_pid
):
with
open
(
self
.
_supervisor_pid
,
'r'
)
as
f
:
with
open
(
self
.
_supervisor_pid
,
'r'
)
as
f
:
try
:
try
:
...
@@ -715,6 +744,7 @@ class StandaloneSlapOS(object):
...
@@ -715,6 +744,7 @@ class StandaloneSlapOS(object):
self
.
_logger
.
debug
(
"Started new supervisor: %s"
,
output
)
self
.
_logger
.
debug
(
"Started new supervisor: %s"
,
output
)
def
_isSlapOSAvailable
(
self
):
def
_isSlapOSAvailable
(
self
):
# type: () -> bool
try
:
try
:
urllib
.
request
.
urlopen
(
self
.
_master_url
).
close
()
urllib
.
request
.
urlopen
(
self
.
_master_url
).
close
()
except
urllib
.
error
.
HTTPError
as
e
:
except
urllib
.
error
.
HTTPError
as
e
:
...
@@ -723,6 +753,7 @@ class StandaloneSlapOS(object):
...
@@ -723,6 +753,7 @@ class StandaloneSlapOS(object):
return
True
return
True
raise
raise
except
urllib
.
error
.
URLError
as
e
:
except
urllib
.
error
.
URLError
as
e
:
assert
isinstance
(
e
.
reason
,
OSError
)
if
e
.
reason
.
errno
==
errno
.
ECONNREFUSED
:
if
e
.
reason
.
errno
==
errno
.
ECONNREFUSED
:
return
False
return
False
raise
raise
...
@@ -735,6 +766,7 @@ class StandaloneSlapOS(object):
...
@@ -735,6 +766,7 @@ class StandaloneSlapOS(object):
return
True
# (if / becomes 200 OK)
return
True
# (if / becomes 200 OK)
def
_ensureSlapOSAvailable
(
self
):
def
_ensureSlapOSAvailable
(
self
):
# type: () -> None
# Wait for proxy to accept connections
# Wait for proxy to accept connections
for
i
in
range
(
2
**
8
):
for
i
in
range
(
2
**
8
):
if
self
.
_isSlapOSAvailable
():
if
self
.
_isSlapOSAvailable
():
...
@@ -743,12 +775,14 @@ class StandaloneSlapOS(object):
...
@@ -743,12 +775,14 @@ class StandaloneSlapOS(object):
raise
RuntimeError
(
"SlapOS not started"
)
raise
RuntimeError
(
"SlapOS not started"
)
def
_getSubprocessEnvironment
(
self
):
def
_getSubprocessEnvironment
(
self
):
# type: () -> Optional[Dict[str, str]]
# Running tests with `python setup.py test` sets a PYTHONPATH that
# Running tests with `python setup.py test` sets a PYTHONPATH that
# is suitable for current python, but problematic when this process
# is suitable for current python, but problematic when this process
# runs another version of python in subprocess.
# runs another version of python in subprocess.
if
'PYTHONPATH'
in
os
.
environ
:
if
'PYTHONPATH'
in
os
.
environ
:
self
.
_logger
.
warning
(
self
.
_logger
.
warning
(
"Removing $PYTHONPATH from environment for subprocess"
)
"Removing $PYTHONPATH from environment for subprocess"
)
env
=
os
.
environ
.
copy
()
env
=
os
.
environ
.
copy
()
del
env
[
'PYTHONPATH'
]
del
env
[
'PYTHONPATH'
]
return
env
return
env
return
None
slapos/tests/test_prune.py
View file @
656a5721
...
@@ -32,10 +32,11 @@ import shutil
...
@@ -32,10 +32,11 @@ import shutil
import
unittest
import
unittest
import
slapos.client
import
slapos.client
try
:
import
sys
import
mock
if
sys
.
version_info
[
0
]
==
3
:
except
ImportError
:
from
unittest
import
mock
from
unittest
import
mock
else
:
import
mock
from
slapos.cli.prune
import
do_prune
from
slapos.cli.prune
import
do_prune
...
...
slapos/tests/test_slapproxy.py
View file @
656a5721
...
@@ -34,10 +34,15 @@ import os
...
@@ -34,10 +34,15 @@ import os
import
logging
import
logging
import
shutil
import
shutil
import
socket
import
socket
try
:
from
typing
import
TYPE_CHECKING
import
subprocess32
as
subprocess
if
TYPE_CHECKING
:
except
ImportError
:
import
subprocess
import
subprocess
else
:
try
:
import
subprocess32
as
subprocess
except
ImportError
:
import
subprocess
import
sys
import
sys
import
tempfile
import
tempfile
import
time
import
time
...
...
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