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
Labels
Merge Requests
22
Merge Requests
22
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
slapos.core
Commits
0448cd02
Commit
0448cd02
authored
4 years ago
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Plain Diff
Support partitions destruction in slap proxy
See merge request
nexedi/slapos.core!250
parents
1b56afdc
846a829e
Pipeline
#11922
failed with stage
Changes
3
Pipelines
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
157 additions
and
6 deletions
+157
-6
slapos/proxy/views.py
slapos/proxy/views.py
+34
-1
slapos/testing/testcase.py
slapos/testing/testcase.py
+4
-2
slapos/tests/test_slapproxy.py
slapos/tests/test_slapproxy.py
+119
-3
No files found.
slapos/proxy/views.py
View file @
0448cd02
...
...
@@ -302,7 +302,40 @@ def stoppedComputerPartition():
@
app
.
route
(
'/destroyedComputerPartition'
,
methods
=
[
'POST'
])
def
destroyedComputerPartition
():
return
'Ignored'
if
not
(
request
.
form
[
'computer_partition_id'
]
and
request
.
form
[
'computer_id'
]):
raise
ValueError
(
"computer_partition_id and computer_id are required"
)
# Implement something similar to Alarm_garbageCollectDestroyUnlinkedInstance, if root instance
# is destroyed, we request child instances in deleted state
execute_db
(
'partition'
,
'UPDATE %s SET requested_state="destroyed" where requested_by=? and computer_reference=?'
,
[
request
.
form
[
'computer_partition_id'
],
request
.
form
[
'computer_id'
]])
non_destroyed_child_partitions
=
[
p
[
'reference'
]
for
p
in
execute_db
(
'partition'
,
'SELECT reference FROM %s WHERE requested_by=? AND computer_reference=?'
,
[
request
.
form
[
'computer_partition_id'
],
request
.
form
[
'computer_id'
]])]
if
non_destroyed_child_partitions
:
return
"Not destroying yet because this partition has child partitions: %s"
%
(
', '
.
join
(
non_destroyed_child_partitions
))
execute_db
(
'partition'
,
'UPDATE %s SET '
' slap_state="free",'
' software_release=NULL,'
' xml=NULL,'
' connection_xml=NULL,'
' slave_instance_list=NULL,'
' software_type=NULL,'
' partition_reference=NULL,'
' requested_by=NULL,'
' requested_state="started"'
'WHERE reference=? AND computer_reference=? '
,
[
request
.
form
[
'computer_partition_id'
],
request
.
form
[
'computer_id'
]])
return
'OK'
@
app
.
route
(
'/useComputer'
,
methods
=
[
'POST'
])
def
useComputer
():
...
...
This diff is collapsed.
Click to expand it.
slapos/testing/testcase.py
View file @
0448cd02
...
...
@@ -700,7 +700,8 @@ class SlapOSInstanceTestCase(unittest.TestCase):
cls
.
_storeSystemSnapshot
(
"{}._cleanup request destroy"
.
format
(
snapshot_name
))
try
:
cls
.
slap
.
waitForReport
(
max_retry
=
cls
.
report_max_retry
,
debug
=
cls
.
_debug
)
for
_
in
range
(
3
):
cls
.
slap
.
waitForReport
(
max_retry
=
cls
.
report_max_retry
,
debug
=
cls
.
_debug
)
except
:
cls
.
logger
.
exception
(
"Error during actual destruction"
)
cls
.
_storeSystemSnapshot
(
...
...
@@ -731,7 +732,8 @@ class SlapOSInstanceTestCase(unittest.TestCase):
"{}._cleanup leaked_partitions request destruction"
.
format
(
snapshot_name
))
try
:
cls
.
slap
.
waitForReport
(
max_retry
=
cls
.
report_max_retry
,
debug
=
cls
.
_debug
)
for
_
in
range
(
3
):
cls
.
slap
.
waitForReport
(
max_retry
=
cls
.
report_max_retry
,
debug
=
cls
.
_debug
)
except
:
cls
.
logger
.
exception
(
"Error during leaked partitions actual destruction"
)
...
...
This diff is collapsed.
Click to expand it.
slapos/tests/test_slapproxy.py
View file @
0448cd02
...
...
@@ -440,6 +440,15 @@ class MasterMixin(BasicMixin, unittest.TestCase):
self
.
assertLessEqual
(
float
(
computer_partition
.
_parameter_dict
[
'timestamp'
]),
requested_at
)
app
=
self
.
app
class
TestConnectionHelper
:
def
GET
(
self
,
path
,
params
=
None
,
headers
=
None
):
return
app
.
get
(
path
,
query_string
=
params
,
data
=
data
).
data
def
POST
(
self
,
path
,
params
=
None
,
data
=
None
,
content_type
=
'application/x-www-form-urlencoded'
):
return
app
.
post
(
path
,
query_string
=
params
,
data
=
data
).
data
computer_partition
.
_connection_helper
=
TestConnectionHelper
()
return
computer_partition
def
supply
(
self
,
url
,
computer_id
=
None
,
state
=
'available'
):
...
...
@@ -582,7 +591,9 @@ class TestRequest(MasterMixin):
self
.
assertLessEqual
(
float
(
str
(
requested_at
)),
float
(
partition
.
_parameter_dict
[
'timestamp'
]))
time
.
sleep
(.
1
)
# check timestamp does not change for an identical request
self
.
assertEqual
(
partition
.
__dict__
,
do_request
().
__dict__
)
self
.
assertEqual
(
dict
(
partition
.
__dict__
,
_connection_helper
=
None
),
dict
(
do_request
().
__dict__
,
_connection_helper
=
None
))
def
test_instance_bang
(
self
):
"""
...
...
@@ -740,8 +751,8 @@ class TestRequest(MasterMixin):
"""
self
.
format_for_number_of_partitions
(
2
)
self
.
assertEqual
(
self
.
request
(
'http://sr//'
,
None
,
'MyFirstInstance'
,
'slappart2'
).
__dict__
,
self
.
request
(
'http://sr//'
,
None
,
'MyFirstInstance'
,
'slappart3'
).
__dict__
)
dict
(
self
.
request
(
'http://sr//'
,
None
,
'MyFirstInstance'
,
'slappart2'
).
__dict__
,
_connection_helper
=
None
)
,
dict
(
self
.
request
(
'http://sr//'
,
None
,
'MyFirstInstance'
,
'slappart3'
).
__dict__
,
_connection_helper
=
None
)
)
def
test_two_different_request_from_one_partition
(
self
):
"""
...
...
@@ -825,6 +836,111 @@ class TestRequest(MasterMixin):
'/'
,
request
.
getConnectionParameterDict
()[
'path'
])
def
test_destroy_partition
(
self
):
self
.
format_for_number_of_partitions
(
1
)
partition
=
self
.
request
(
'http://sr//'
,
None
,
'MyFirstInstance'
)
self
.
assertEqual
(
partition
.
getState
(),
'started'
)
partition
=
self
.
request
(
'http://sr//'
,
None
,
'MyFirstInstance'
,
state
=
'destroyed'
)
self
.
assertEqual
(
partition
.
getState
(),
'destroyed'
)
partition_data
,
=
slapos
.
proxy
.
views
.
execute_db
(
'partition'
,
'SELECT * from %s where reference=?'
,
(
partition
.
getId
(),),
db
=
sqlite_connect
(
self
.
proxy_db
))
self
.
assertEqual
(
partition_data
[
'requested_state'
],
'destroyed'
)
self
.
assertEqual
(
partition_data
[
'slap_state'
],
'busy'
)
self
.
assertEqual
(
partition_data
[
'software_release'
],
'http://sr//'
)
self
.
assertEqual
(
partition_data
[
'partition_reference'
],
'MyFirstInstance'
)
partition
.
destroyed
()
# this is what `slapos node report` call
# now partition is free
partition_data
,
=
slapos
.
proxy
.
views
.
execute_db
(
'partition'
,
'SELECT * from %s where reference=?'
,
(
partition
.
getId
(),),
db
=
sqlite_connect
(
self
.
proxy_db
))
self
.
assertEqual
(
partition_data
[
'requested_state'
],
'started'
)
self
.
assertEqual
(
partition_data
[
'slap_state'
],
'free'
)
self
.
assertIsNone
(
partition_data
[
'partition_reference'
])
# and we can request new partitions
self
.
request
(
'http://sr//'
,
None
,
'Another instance'
)
def
test_destroy_child_partition
(
self
):
self
.
format_for_number_of_partitions
(
2
)
partition_parent
=
self
.
request
(
'http://sr//'
,
None
,
'MyFirstInstance'
)
partition_child
=
self
.
request
(
'http://sr//'
,
None
,
'MySubInstance'
,
partition_parent
.
getId
())
self
.
assertEqual
(
partition_parent
.
getState
(),
'started'
)
self
.
assertEqual
(
partition_child
.
getState
(),
'started'
)
partition_parent
=
self
.
request
(
'http://sr//'
,
None
,
'MyFirstInstance'
,
state
=
'destroyed'
)
self
.
assertEqual
(
slapos
.
proxy
.
views
.
execute_db
(
'partition'
,
'SELECT reference, slap_state, requested_by, requested_state from %s order by requested_by'
,
db
=
sqlite_connect
(
self
.
proxy_db
),
),
[
{
'reference'
:
partition_parent
.
getId
(),
'slap_state'
:
'busy'
,
'requested_by'
:
None
,
'requested_state'
:
'destroyed'
,
},
{
'reference'
:
partition_child
.
getId
(),
'slap_state'
:
'busy'
,
'requested_by'
:
partition_parent
.
getId
(),
'requested_state'
:
'started'
,
},
])
# destroying the parent partition will first mark the dependent partitions as destroyed
partition_parent
.
destroyed
()
self
.
assertEqual
(
slapos
.
proxy
.
views
.
execute_db
(
'partition'
,
'SELECT reference, slap_state, requested_by, requested_state from %s order by requested_by'
,
db
=
sqlite_connect
(
self
.
proxy_db
),
),
[
{
'reference'
:
partition_parent
.
getId
(),
'slap_state'
:
'busy'
,
'requested_by'
:
None
,
'requested_state'
:
'destroyed'
,
},
{
'reference'
:
partition_child
.
getId
(),
'slap_state'
:
'busy'
,
'requested_by'
:
partition_parent
.
getId
(),
'requested_state'
:
'destroyed'
,
},
])
partition_parent
.
destroyed
()
partition_child
.
destroyed
()
partition_parent
.
destroyed
()
self
.
assertEqual
(
slapos
.
proxy
.
views
.
execute_db
(
'partition'
,
'SELECT reference, slap_state, requested_by, requested_state from %s order by requested_by'
,
db
=
sqlite_connect
(
self
.
proxy_db
),
),
[
{
'reference'
:
partition_parent
.
getId
(),
'slap_state'
:
'free'
,
'requested_by'
:
None
,
'requested_state'
:
'started'
,
},
{
'reference'
:
partition_child
.
getId
(),
'slap_state'
:
'free'
,
'requested_by'
:
None
,
'requested_state'
:
'started'
,
},
])
class
TestSlaveRequest
(
MasterMixin
):
"""
...
...
This diff is collapsed.
Click to expand it.
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