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
Arnaud Véron
slapos.core
Commits
9998c6f4
Commit
9998c6f4
authored
Jun 30, 2022
by
Rafael Monnerat
Browse files
Options
Browse Files
Download
Plain Diff
Clean up for the JSON API work
See merge request
!388
parents
1ac3ec59
e36b68d4
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
649 additions
and
389 deletions
+649
-389
master/bt5/slapos_cloud/DocumentTemplateItem/portal_components/document.erp5.SoftwareInstance.py
...eItem/portal_components/document.erp5.SoftwareInstance.py
+10
-23
master/bt5/slapos_cloud/DocumentTemplateItem/portal_components/document.erp5.SoftwareInstance.xml
...Item/portal_components/document.erp5.SoftwareInstance.xml
+3
-24
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSCatalogToolCacheMixin.py
...rtal_components/mixin.erp5.SlapOSCatalogToolCacheMixin.py
+94
-0
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSCatalogToolCacheMixin.xml
...tal_components/mixin.erp5.SlapOSCatalogToolCacheMixin.xml
+112
-0
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSComputeNodeMixin.py
...em/portal_components/mixin.erp5.SlapOSComputeNodeMixin.py
+55
-73
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSComputeNodeMixin.xml
...m/portal_components/mixin.erp5.SlapOSComputeNodeMixin.xml
+3
-24
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSComputePartitionMixin.py
...rtal_components/mixin.erp5.SlapOSComputePartitionMixin.py
+56
-38
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSComputePartitionMixin.xml
...tal_components/mixin.erp5.SlapOSComputePartitionMixin.xml
+3
-24
master/bt5/slapos_cloud/ModuleComponentTemplateItem/portal_components/module.erp5.SlapOSCloud.py
...TemplateItem/portal_components/module.erp5.SlapOSCloud.py
+38
-0
master/bt5/slapos_cloud/ModuleComponentTemplateItem/portal_components/module.erp5.SlapOSCloud.xml
...emplateItem/portal_components/module.erp5.SlapOSCloud.xml
+112
-0
master/bt5/slapos_cloud/PortalTypeTypeMixinTemplateItem/type_mixin.xml
...apos_cloud/PortalTypeTypeMixinTemplateItem/type_mixin.xml
+3
-0
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloud.py
...mplateItem/portal_components/test.erp5.testSlapOSCloud.py
+1
-1
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloud.xml
...plateItem/portal_components/test.erp5.testSlapOSCloud.xml
+3
-24
master/bt5/slapos_cloud/bt/template_mixin_id_list
master/bt5/slapos_cloud/bt/template_mixin_id_list
+2
-1
master/bt5/slapos_cloud/bt/template_module_component_id_list
master/bt5/slapos_cloud/bt/template_module_component_id_list
+1
-0
master/bt5/slapos_cloud/bt/template_portal_type_type_mixin_list
.../bt5/slapos_cloud/bt/template_portal_type_type_mixin_list
+1
-0
master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapTool.py
...ateItem/portal_components/test.erp5.testSlapOSSlapTool.py
+17
-6
master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapTool.xml
...teItem/portal_components/test.erp5.testSlapOSSlapTool.xml
+3
-24
master/bt5/slapos_slap_tool/ToolComponentTemplateItem/portal_components/tool.erp5.SlapTool.py
...onentTemplateItem/portal_components/tool.erp5.SlapTool.py
+129
-103
master/bt5/slapos_slap_tool/ToolComponentTemplateItem/portal_components/tool.erp5.SlapTool.xml
...nentTemplateItem/portal_components/tool.erp5.SlapTool.xml
+3
-24
No files found.
master/bt5/slapos_cloud/DocumentTemplateItem/portal_components/document.erp5.SoftwareInstance.py
View file @
9998c6f4
...
...
@@ -31,31 +31,18 @@ from erp5.component.document.Item import Item
from
lxml
import
etree
import
collections
from
AccessControl
import
Unauthorized
from
AccessControl.Permissions
import
access_contents_information
from
AccessControl
import
getSecurityManager
from
Products.ERP5Type.UnrestrictedMethod
import
UnrestrictedMethod
from
erp5.component.module.SlapOSCloud
import
_assertACI
from
zLOG
import
LOG
,
INFO
try
:
from
slapos.slap.slap
import
\
SoftwareInstance
as
SlapSoftwareInstance
from
slapos.util
import
xml2dict
,
loads
except
ImportError
:
def
xml2dict
(
dictionary
):
raise
ImportError
def
loads
(
*
args
):
raise
ImportError
class
SlapSoftwareInstance
:
def
__init__
(
self
):
raise
ImportError
def
_assertACI
(
document
):
sm
=
getSecurityManager
()
if
sm
.
checkPermission
(
access_contents_information
,
document
):
return
document
raise
Unauthorized
(
'User %r has no access to %r'
%
(
sm
.
getUser
(),
document
))
class
DisconnectedSoftwareTree
(
Exception
):
pass
...
...
@@ -160,7 +147,7 @@ class SoftwareInstance(Item):
LOG
(
'SoftwareInstance'
,
INFO
,
'Issue during parsing xml:'
,
error
=
True
)
return
result_dict
def
_asSoftwareInstance
(
self
):
def
_asSoftwareInstance
Dict
(
self
):
parameter_dict
=
self
.
_asParameterDict
()
requested_state
=
self
.
getSlapState
()
...
...
@@ -182,13 +169,13 @@ class SoftwareInstance(Item):
parameter_dict
.
pop
(
'filter_xml'
))
instance_guid
=
parameter_dict
.
pop
(
'instance_guid'
)
software_instance
=
SlapSoftwareInstance
(
**
parameter_dict
)
software_instance
.
_parameter_dict
=
xml
software_instance
.
_connection_dict
=
connection_xml
software_instance
.
_filter_dict
=
filter_xml
software_instance
.
_requested_state
=
state
software_instance
.
_instance_guid
=
instance_guid
return
software_instance
software_instance
_dict
=
parameter_dict
software_instance
_dict
[
'_parameter_dict'
]
=
xml
software_instance
_dict
[
'_connection_dict'
]
=
connection_xml
software_instance
_dict
[
'_filter_dict'
]
=
filter_xml
software_instance
_dict
[
'_requested_state'
]
=
state
software_instance
_dict
[
'_instance_guid'
]
=
instance_guid
return
software_instance
_dict
@
UnrestrictedMethod
def
_asParameterDict
(
self
,
shared_instance_sql_list
=
None
):
...
...
master/bt5/slapos_cloud/DocumentTemplateItem/portal_components/document.erp5.SoftwareInstance.xml
View file @
9998c6f4
...
...
@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_recorded_property_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
SoftwareInstance
</string>
</value>
...
...
@@ -55,28 +49,13 @@
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
I
=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
...
...
@@ -89,7 +68,7 @@
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
Q
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
</value>
</item>
</dictionary>
...
...
@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record
id=
"
4"
aka=
"AAAAAAAAAAQ
="
>
<record
id=
"
3"
aka=
"AAAAAAAAAAM
="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
...
...
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSCatalogToolCacheMixin.py
0 → 100644
View file @
9998c6f4
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010-2022 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 advised 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 2
# 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
erp5.component.module.SlapOSCloud
import
_assertACI
from
OFS.Traversable
import
NotFound
from
Products.ERP5Type.Cache
import
CachingMethod
from
Products.ERP5Type.UnrestrictedMethod
import
UnrestrictedMethod
class
SlapOSCatalogToolCacheMixin
(
object
):
""" Quering Caching Extension for Catalog for handle specific queries
relying on caching.
The searches also differ NotFound from Unauthorized, by relying into
unrestricted searches and a custom way to assert Access roles.
Be carefull to not rely on it to hack arround security.
"""
def
_getNonCachedComputeNode
(
self
,
reference
):
# No need to get all results if an error is raised when at least 2 objects
# are found
compute_node_list
=
self
.
unrestrictedSearchResults
(
limit
=
2
,
portal_type
=
'Compute Node'
,
validation_state
=
"validated"
,
reference
=
reference
)
if
len
(
compute_node_list
)
!=
1
:
raise
NotFound
,
"No document found with parameters: %s"
%
reference
else
:
return
_assertACI
(
compute_node_list
[
0
].
getObject
()).
getRelativeUrl
()
def
getComputeNodeObject
(
self
,
reference
):
"""
Get the validated compute_node with this reference.
"""
result
=
CachingMethod
(
self
.
_getNonCachedComputeNode
,
id
=
'_getComputeNodeObject'
,
cache_factory
=
'slap_cache_factory'
)(
reference
)
return
self
.
getPortalObject
().
restrictedTraverse
(
result
)
@
UnrestrictedMethod
def
_getComputeNodeUid
(
self
,
reference
):
"""
Get the validated compute_node with this reference.
"""
return
CachingMethod
(
self
.
_getNonCachedComputeNodeUid
,
id
=
'_getNonCachedComputeNodeUid'
,
cache_factory
=
'slap_cache_factory'
)(
reference
)
@
UnrestrictedMethod
def
_getNonCachedComputeNodeUid
(
self
,
reference
):
return
self
.
unrestrictedSearchResults
(
portal_type
=
'Compute Node'
,
reference
=
reference
,
validation_state
=
"validated"
)[
0
].
UID
def
getComputePartitionObject
(
self
,
compute_node_reference
,
compute_partition_reference
):
"""
Get the compute partition defined in an available compute_node
"""
# Related key might be nice
compute_partition_list
=
self
.
unrestrictedSearchResults
(
limit
=
2
,
portal_type
=
'Compute Partition'
,
reference
=
compute_partition_reference
,
parent_uid
=
self
.
_getNonCachedComputeNodeUid
(
compute_node_reference
))
if
len
(
compute_partition_list
)
!=
1
:
raise
NotFound
,
"No document found with parameters: %s %s"
%
\
(
compute_node_reference
,
compute_partition_reference
)
else
:
return
_assertACI
(
compute_partition_list
[
0
].
getObject
())
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSCatalogToolCacheMixin.xml
0 → 100644
View file @
9998c6f4
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Mixin Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
SlapOSCatalogToolCacheMixin
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
mixin.erp5.SlapOSCatalogToolCacheMixin
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Mixin Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSComputeNodeMixin.py
View file @
9998c6f4
...
...
@@ -28,46 +28,22 @@
from
Products.ERP5Type.Cache
import
DEFAULT_CACHE_SCOPE
from
AccessControl
import
Unauthorized
from
AccessControl.Permissions
import
access_contents_information
from
AccessControl
import
getSecurityManager
from
Products.ERP5Type.UnrestrictedMethod
import
UnrestrictedMethod
from
Products.ERP5Type.tests.utils
import
DummyMailHostMixin
from
OFS.Traversable
import
NotFound
from
erp5.component.module.SlapOSCloud
import
_assertACI
import
time
from
lxml
import
etree
from
zLOG
import
LOG
,
INFO
try
:
from
slapos.slap.slap
import
(
Computer
as
ComputeNode
,
ComputerPartition
as
SlapComputePartition
,
SoftwareRelease
)
from
slapos.util
import
xml2dict
,
dumps
from
slapos.util
import
xml2dict
except
ImportError
:
# Do no prevent instance from starting
# if libs are not installed
class
ComputeNode
:
def
__init__
(
self
):
raise
ImportError
class
SlapComputePartition
:
def
__init__
(
self
):
raise
ImportError
class
SoftwareRelease
:
def
__init__
(
self
):
raise
ImportError
def
xml2dict
(
dictionary
):
raise
ImportError
def
dumps
(
*
args
):
raise
ImportError
def
_assertACI
(
document
):
sm
=
getSecurityManager
()
if
sm
.
checkPermission
(
access_contents_information
,
document
):
return
document
raise
Unauthorized
(
'User %r has no access to %r'
%
(
sm
.
getUser
(),
document
))
class
SlapOSComputeNodeMixin
(
object
):
...
...
@@ -87,42 +63,42 @@ class SlapOSComputeNodeMixin(object):
validation_state
=
'validated'
,
):
software_installation
=
_assertACI
(
software_installation
.
getObject
())
software_release_response
=
SoftwareRelease
(
software_release
=
software_installation
.
getUrlString
().
decode
(
'UTF-8'
),
computer_guid
=
self
.
getReference
().
decode
(
'UTF-8'
))
software_release_dict
=
{
"software_release"
:
software_installation
.
getUrlString
().
decode
(
'UTF-8'
),
"computer_guid"
:
self
.
getReference
().
decode
(
'UTF-8'
)
}
if
software_installation
.
getSlapState
()
==
'destroy_requested'
:
software_release_
response
.
_requested_state
=
'destroyed'
software_release_
dict
[
"_requested_state"
]
=
'destroyed'
else
:
software_release_
response
.
_requested_state
=
'available'
software_release_
dict
[
"_requested_state"
]
=
'available'
known_state
=
software_installation
.
getTextAccessStatus
()
if
known_state
.
startswith
(
"#access"
):
software_release_
response
.
_known_state
=
'available'
software_release_
dict
[
"_known_state"
]
=
'available'
elif
known_state
.
startswith
(
"#building"
):
software_release_
response
.
_known_state
=
'building'
software_release_
dict
[
"_known_state"
]
=
'building'
else
:
software_release_
response
.
_known_state
=
'error'
software_release_
dict
[
"_known_state"
]
=
'error'
software_release_list
.
append
(
software_release_
response
)
software_release_list
.
append
(
software_release_
dict
)
return
software_release_list
def
_getCacheComputeNodeInformation
(
self
,
user
):
self
.
REQUEST
.
response
.
setHeader
(
'Content-Type'
,
'text/xml; charset=utf-8'
)
slap_compute_node
=
ComputeNode
(
self
.
getReference
().
decode
(
"UTF-8"
))
slap_compute_node
.
_computer_partition_list
=
[]
slap_compute_node
.
_software_release_list
=
self
.
_getSoftwareReleaseValueList
()
compute_node_dict
=
{
"_computer_id"
:
self
.
getReference
().
decode
(
"UTF-8"
),
"_computer_partition_list"
:
[],
"_software_release_list"
:
self
.
_getSoftwareReleaseValueList
()
}
unrestrictedSearchResults
=
self
.
getPortalObject
().
portal_catalog
.
unrestrictedSearchResults
compute_partition_list
=
unrestrictedSearchResults
(
parent_uid
=
self
.
getUid
(),
validation_state
=
"validated"
,
portal_type
=
"Compute Partition"
)
self
.
_calculateSlapComputeNodeInformation
(
slap_compute_node
,
compute_partition_list
)
self
.
_calculateSlapComputeNodeInformation
(
compute_node_dict
,
compute_partition_list
)
return
dumps
(
slap_compute_node
)
return
compute_node_dict
def
_activateFillComputeNodeInformationCache
(
self
,
user
):
tag
=
'compute_node_information_cache_fill_%s_%s'
%
(
self
.
getReference
(),
user
)
...
...
@@ -133,11 +109,14 @@ class SlapOSComputeNodeMixin(object):
def
_fillComputeNodeInformationCache
(
self
,
user
):
key
=
'%s_%s'
%
(
self
.
getReference
(),
user
)
try
:
computer_dict
=
self
.
_getCacheComputeNodeInformation
(
user
)
self
.
_getCachePlugin
().
set
(
key
,
DEFAULT_CACHE_SCOPE
,
dict
(
time
=
time
.
time
(),
refresh_etag
=
self
.
_calculateRefreshEtag
(),
data
=
self
.
_getCacheComputeNodeInformation
(
user
),
data
=
computer_dict
,
# Store the XML while SlapTool Still used
data_xml
=
self
.
getPortalObject
().
portal_slap
.
_getSlapComputeNodeXMLFromDict
(
computer_dict
)
),
cache_duration
=
self
.
getPortalObject
().
portal_caches
\
.
getRamCacheRoot
().
get
(
'compute_node_information_cache_factory'
\
...
...
@@ -178,11 +157,7 @@ class SlapOSComputeNodeMixin(object):
user_document
=
_assertACI
(
portal
.
portal_catalog
.
unrestrictedGetResultValue
(
reference
=
user
,
portal_type
=
[
'Person'
,
'Compute Node'
,
'Software Instance'
]))
user_type
=
user_document
.
getPortalType
()
self
.
REQUEST
.
response
.
setHeader
(
'Content-Type'
,
'text/xml; charset=utf-8'
)
slap_compute_node
=
ComputeNode
(
self
.
getReference
().
decode
(
"UTF-8"
))
slap_compute_node
.
_computer_partition_list
=
[]
if
user_type
in
(
'Compute Node'
,
'Person'
):
if
not
self
.
_isTestRun
():
cache_plugin
=
self
.
_getCachePlugin
()
...
...
@@ -207,22 +182,27 @@ class SlapOSComputeNodeMixin(object):
else
:
return
self
.
_getCacheComputeNodeInformation
(
user
),
None
else
:
slap_compute_node
.
_software_release_list
=
[]
compute_node_dict
=
{
"_computer_id"
:
self
.
getReference
().
decode
(
"UTF-8"
),
"_computer_partition_list"
:
[],
"_software_release_list"
:
[]
}
if
user_type
==
'Software Instance'
:
compute_partition_list
=
self
.
contentValues
(
portal_type
=
"Compute Partition"
,
checked_permission
=
"View"
)
else
:
compute_partition_list
=
self
.
getPortalObject
().
portal_catalog
.
unrestrictedSearchResults
(
unrestrictedSearchResults
=
self
.
getPortalObject
().
portal_catalog
.
unrestrictedSearchResults
compute_partition_list
=
unrestrictedSearchResults
(
parent_uid
=
self
.
getUid
(),
validation_state
=
"validated"
,
portal_type
=
"Compute Partition"
)
self
.
_calculateSlapComputeNodeInformation
(
slap_compute_node
,
compute_partition_list
)
return
dumps
(
slap_compute_node
)
,
None
self
.
_calculateSlapComputeNodeInformation
(
compute_node_dict
,
compute_partition_list
)
return
compute_node_dict
,
None
def
_calculateSlapComputeNodeInformation
(
self
,
slap_compute_node
,
compute_partition_list
):
def
_calculateSlapComputeNodeInformation
(
self
,
compute_node_dict
,
compute_partition_list
):
if
len
(
compute_partition_list
)
==
0
:
return
...
...
@@ -248,7 +228,7 @@ class SlapOSComputeNodeMixin(object):
software_instance_list
=
[
x
for
x
in
grouped_software_instance_list
if
(
x
.
default_aggregate_uid
==
compute_partition
.
getUid
())]
if
(
len
(
software_instance_list
)
==
1
)
and
(
software_instance_list
[
0
][
'count(*)'
]
>
1
):
software_instance_list
=
software_instance_list
+
software_instance_list
slap_compute_node
.
_computer_partition_list
.
append
(
compute_node_dict
[
'_computer_partition_list'
]
.
append
(
self
.
_getSlapPartitionByPackingList
(
_assertACI
(
compute_partition
.
getObject
()),
software_instance_list
,
...
...
@@ -273,12 +253,13 @@ class SlapOSComputeNodeMixin(object):
while
compute_node
.
getPortalType
()
!=
'Compute Node'
:
compute_node
=
compute_node
.
getParentValue
()
compute_node_id
=
compute_node
.
getReference
().
decode
(
"UTF-8"
)
slap_partition
=
SlapComputePartition
(
compute_node_id
,
compute_partition_document
.
getReference
().
decode
(
"UTF-8"
))
slap_partition
.
_software_release_document
=
None
slap_partition
.
_requested_state
=
'destroyed'
slap_partition
.
_need_modification
=
0
partition_dict
=
{
"compute_node_id"
:
compute_node_id
,
"partition_id"
:
compute_partition_document
.
getReference
().
decode
(
"UTF-8"
),
"_software_release_document"
:
None
,
"_requested_state"
:
'destroyed'
,
"_need_modification"
:
0
}
software_instance
=
None
...
...
@@ -294,28 +275,29 @@ class SlapOSComputeNodeMixin(object):
if
software_instance
is
not
None
:
state
=
software_instance
.
getSlapState
()
if
state
==
"stop_requested"
:
slap_partition
.
_requested_state
=
'stopped'
partition_dict
[
'_requested_state'
]
=
'stopped'
if
state
==
"start_requested"
:
slap_partition
.
_requested_state
=
'started'
slap_partition
.
_access_status
=
software_instance
.
getTextAccessStatus
()
partition_dict
[
'_requested_state'
]
=
'started'
partition_dict
[
'_access_status'
]
=
software_instance
.
getTextAccessStatus
()
slap_partition
.
_software_release_document
=
SoftwareRelease
(
software_release
=
software_instance
.
getUrlString
().
decode
(
"UTF-8"
),
computer_guid
=
compute_node_id
)
partition_dict
[
'_software_release_document'
]
=
{
"software_release"
:
software_instance
.
getUrlString
().
decode
(
"UTF-8"
),
"computer_guid"
:
compute_node_id
}
slap_partition
.
_need_modification
=
1
partition_dict
[
"_need_modification"
]
=
1
parameter_dict
=
software_instance
.
_asParameterDict
(
shared_instance_sql_list
=
shared_instance_sql_list
)
# software instance has to define an xml parameter
slap_partition
.
_parameter_dict
=
self
.
_instanceXmlToDict
(
partition_dict
[
"_parameter_dict"
]
=
self
.
_instanceXmlToDict
(
parameter_dict
.
pop
(
'xml'
))
slap_partition
.
_connection_dict
=
self
.
_instanceXmlToDict
(
partition_dict
[
'_connection_dict'
]
=
self
.
_instanceXmlToDict
(
parameter_dict
.
pop
(
'connection_xml'
))
slap_partition
.
_filter_dict
=
self
.
_instanceXmlToDict
(
partition_dict
[
'_filter_dict'
]
=
self
.
_instanceXmlToDict
(
parameter_dict
.
pop
(
'filter_xml'
))
slap_partition
.
_instance_guid
=
parameter_dict
.
pop
(
'instance_guid'
)
partition_dict
[
'_instance_guid'
]
=
parameter_dict
.
pop
(
'instance_guid'
)
for
slave_instance_dict
in
parameter_dict
.
get
(
"slave_instance_list"
,
[]):
if
slave_instance_dict
.
has_key
(
"connection_xml"
):
slave_instance_dict
.
update
(
self
.
_instanceXmlToDict
(
...
...
@@ -323,9 +305,9 @@ class SlapOSComputeNodeMixin(object):
if
slave_instance_dict
.
has_key
(
"xml"
):
slave_instance_dict
.
update
(
self
.
_instanceXmlToDict
(
slave_instance_dict
.
pop
(
"xml"
)))
slap_partition
.
_parameter_dict
.
update
(
parameter_dict
)
partition_dict
[
'_parameter_dict'
]
.
update
(
parameter_dict
)
return
slap_partition
return
partition_dict
def
_getSoftwareInstallationFromUrl
(
self
,
url
):
software_installation_list
=
self
.
getPortalObject
().
portal_catalog
.
unrestrictedSearchResults
(
...
...
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSComputeNodeMixin.xml
View file @
9998c6f4
...
...
@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_recorded_property_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
SlapOSComputeNodeMixin
</string>
</value>
...
...
@@ -55,28 +49,13 @@
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
I
=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
...
...
@@ -89,7 +68,7 @@
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
Q
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
</value>
</item>
</dictionary>
...
...
@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record
id=
"
4"
aka=
"AAAAAAAAAAQ
="
>
<record
id=
"
3"
aka=
"AAAAAAAAAAM
="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
...
...
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSComputePartitionMixin.py
View file @
9998c6f4
...
...
@@ -25,14 +25,11 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
AccessControl.Permissions
import
access_contents_information
from
AccessControl
import
getSecurityManager
from
AccessControl
import
Unauthorize
d
from
erp5.component.module.SlapOSCloud
import
_assertACI
from
zLOG
import
LOG
,
INFO
from
OFS.Traversable
import
NotFoun
d
try
:
from
slapos.slap.slap
import
(
ComputerPartition
as
SlapComputePartition
,
SoftwareRelease
)
from
slapos.util
import
calculate_dict_hash
except
ImportError
:
# Do no prevent instance from starting
...
...
@@ -46,27 +43,48 @@ except ImportError:
def
calculate_dict_hash
(
*
args
):
raise
ImportError
def
_assertACI
(
document
):
sm
=
getSecurityManager
()
if
sm
.
checkPermission
(
access_contents_information
,
document
):
return
document
raise
Unauthorized
(
'User %r has no access to %r'
%
(
sm
.
getUser
(),
document
))
class
SlapOSComputePartitionMixin
(
object
):
def
_getSoftwareInstance
(
self
,
slave_reference
=
None
):
if
self
.
getSlapState
()
!=
'busy'
:
LOG
(
'SlapOSComputePartitionMixin::_getSoftwareInstance'
,
INFO
,
'Compute partition %s shall be busy, is free'
%
self
.
getRelativeUrl
())
raise
NotFound
(
"No software instance found for: %s - %s"
%
(
self
.
getParentValue
().
getTitle
(),
self
.
getTitle
()))
else
:
query_kw
=
{
'validation_state'
:
'validated'
,
'portal_type'
:
'Slave Instance'
,
'default_aggregate_uid'
:
self
.
getUid
(),
}
if
slave_reference
is
None
:
query_kw
[
'portal_type'
]
=
"Software Instance"
else
:
query_kw
[
'reference'
]
=
slave_reference
class
SlapOSComputePartitionMixin
(
object
):
software_instance
=
_assertACI
(
self
.
getPortalObject
().
portal_catalog
.
unrestrictedGetResultValue
(
**
query_kw
))
if
software_instance
is
None
:
raise
NotFound
(
"No software instance found for: %s - %s"
%
(
self
.
getParentValue
().
getTitle
(),
self
.
getTitle
()))
else
:
return
software_instance
def
_registerComputePartition
(
self
):
portal
=
self
.
getPortalObject
()
computer_reference
=
self
.
getParentValue
().
getReference
()
computer_partition_reference
=
self
.
getReference
()
compute_node
=
self
while
compute_node
.
getPortalType
()
!=
'Compute Node'
:
compute_node
=
compute_node
.
getParentValue
()
compute_node_id
=
compute_node
.
getReference
().
decode
(
"UTF-8"
)
slap_partition
=
SlapComputePartition
(
computer_reference
.
decode
(
"UTF-8"
),
computer_partition_reference
.
decode
(
"UTF-8"
))
slap_partition
.
_software_release_document
=
None
slap_partition
.
_requested_state
=
'destroyed'
slap_partition
.
_need_modification
=
0
software_instance
=
None
partition_dict
=
{
"compute_node_id"
:
compute_node_id
,
"partition_id"
:
self
.
getReference
().
decode
(
"UTF-8"
),
"_software_release_document"
:
None
,
"_requested_state"
:
'destroyed'
,
"_need_modification"
:
0
}
if
self
.
getSlapState
()
==
'busy'
:
software_instance_list
=
portal
.
portal_catalog
.
unrestrictedSearchResults
(
...
...
@@ -85,31 +103,31 @@ class SlapOSComputePartitionMixin(object):
self
.
getRelativeUrl
())
if
software_instance
is
not
None
:
# trick client side, that data has been synchronised already for given
# document
slap_partition
.
_synced
=
True
state
=
software_instance
.
getSlapState
()
if
state
==
"stop_requested"
:
slap_partition
.
_requested_state
=
'stopped'
partition_dict
[
'_requested_state'
]
=
'stopped'
if
state
==
"start_requested"
:
slap_partition
.
_requested_state
=
'started'
partition_dict
[
'_requested_state'
]
=
'started'
slap_partition
.
_software_release_document
=
SoftwareRelease
(
software_release
=
software_instance
.
getUrlString
().
decode
(
"UTF-8"
),
computer_guid
=
computer_reference
.
decode
(
"UTF-8"
))
slap_partition
.
_need_modification
=
1
partition_dict
[
'_software_release_document'
]
=
{
"software_release"
:
software_instance
.
getUrlString
().
decode
(
"UTF-8"
),
"computer_guid"
:
compute_node_id
}
partition_dict
[
'_access_status'
]
=
software_instance
.
getTextAccessStatus
()
partition_dict
[
"_need_modification"
]
=
1
# trick client side, that data has been synchronised already for given
# document
partition_dict
[
"_synced"
]
=
True
parameter_dict
=
software_instance
.
_asParameterDict
()
# software instance has to define an xml parameter
slap_partition
.
_parameter_dict
=
software_instance
.
_instanceXmlToDict
(
partition_dict
[
"_parameter_dict"
]
=
software_instance
.
_instanceXmlToDict
(
parameter_dict
.
pop
(
'xml'
))
slap_partition
.
_connection_dict
=
software_instance
.
_instanceXmlToDict
(
partition_dict
[
'_connection_dict'
]
=
software_instance
.
_instanceXmlToDict
(
parameter_dict
.
pop
(
'connection_xml'
))
slap_partition
.
_filter_dict
=
software_instance
.
_instanceXmlToDict
(
partition_dict
[
'_filter_dict'
]
=
software_instance
.
_instanceXmlToDict
(
parameter_dict
.
pop
(
'filter_xml'
))
slap_partition
.
_instance_guid
=
parameter_dict
.
pop
(
'instance_guid'
)
partition_dict
[
'_instance_guid'
]
=
parameter_dict
.
pop
(
'instance_guid'
)
for
slave_instance_dict
in
parameter_dict
.
get
(
"slave_instance_list"
,
[]):
if
slave_instance_dict
.
has_key
(
"connection_xml"
):
connection_dict
=
software_instance
.
_instanceXmlToDict
(
...
...
@@ -120,6 +138,6 @@ class SlapOSComputePartitionMixin(object):
if
slave_instance_dict
.
has_key
(
"xml"
):
slave_instance_dict
.
update
(
software_instance
.
_instanceXmlToDict
(
slave_instance_dict
.
pop
(
"xml"
)))
slap_partition
.
_parameter_dict
.
update
(
parameter_dict
)
partition_dict
[
'_parameter_dict'
]
.
update
(
parameter_dict
)
return
slap_partition
return
partition_dict
master/bt5/slapos_cloud/MixinTemplateItem/portal_components/mixin.erp5.SlapOSComputePartitionMixin.xml
View file @
9998c6f4
...
...
@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_recorded_property_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
SlapOSComputePartitionMixin
</string>
</value>
...
...
@@ -61,28 +55,13 @@
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
I
=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
...
...
@@ -95,7 +74,7 @@
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
Q
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
</value>
</item>
</dictionary>
...
...
@@ -104,7 +83,7 @@
</dictionary>
</pickle>
</record>
<record
id=
"
4"
aka=
"AAAAAAAAAAQ
="
>
<record
id=
"
3"
aka=
"AAAAAAAAAAM
="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
...
...
master/bt5/slapos_cloud/ModuleComponentTemplateItem/portal_components/module.erp5.SlapOSCloud.py
0 → 100644
View file @
9998c6f4
##############################################################################
#
# Copyright (c) 2021 Nexedi SA and Contributors. All Rights Reserved.
#
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability 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
# garantees 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 2
# 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
AccessControl
import
getSecurityManager
from
zExceptions
import
Unauthorized
from
AccessControl.Permissions
import
access_contents_information
def
_assertACI
(
document
):
sm
=
getSecurityManager
()
if
sm
.
checkPermission
(
access_contents_information
,
document
):
return
document
raise
Unauthorized
(
'User %r has no access to %r'
%
(
sm
.
getUser
(),
document
))
\ No newline at end of file
master/bt5/slapos_cloud/ModuleComponentTemplateItem/portal_components/module.erp5.SlapOSCloud.xml
0 → 100644
View file @
9998c6f4
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Module Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
SlapOSCloud
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
module.erp5.SlapOSCloud
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Module Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_cloud/PortalTypeTypeMixinTemplateItem/type_mixin.xml
View file @
9998c6f4
<type_mixin>
<portal_type
id=
"Catalog Tool"
>
<item>
SlapOSCatalogToolCacheMixin
</item>
</portal_type>
<portal_type
id=
"Compute Node"
>
<item>
SlapOSCacheMixin
</item>
<item>
SlapOSComputeNodeMixin
</item>
...
...
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloud.py
View file @
9998c6f4
...
...
@@ -35,7 +35,7 @@ import hashlib
from
binascii
import
hexlify
def
hashData
(
data
):
return
hexlify
(
hashlib
.
sha1
(
data
).
digest
())
return
hexlify
(
hashlib
.
sha1
(
json
.
dumps
(
data
,
sort_keys
=
True
)
).
digest
())
class
TestSlapOSCloudSlapOSCacheMixin
(
SlapOSTestCaseMixin
):
...
...
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloud.xml
View file @
9998c6f4
...
...
@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_recorded_property_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
testSlapOSCloud
</string>
</value>
...
...
@@ -61,28 +55,13 @@
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
I
=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
...
...
@@ -95,7 +74,7 @@
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
Q
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
</value>
</item>
</dictionary>
...
...
@@ -104,7 +83,7 @@
</dictionary>
</pickle>
</record>
<record
id=
"
4"
aka=
"AAAAAAAAAAQ
="
>
<record
id=
"
3"
aka=
"AAAAAAAAAAM
="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
...
...
master/bt5/slapos_cloud/bt/template_mixin_id_list
View file @
9998c6f4
mixin.erp5.SlapOSCacheMixin
mixin.erp5.SlapOSComputeNodeMixin
mixin.erp5.SlapOSComputePartitionMixin
mixin.erp5.SlapOSCatalogToolCacheMixin
\ No newline at end of file
master/bt5/slapos_cloud/bt/template_module_component_id_list
0 → 100644
View file @
9998c6f4
module.erp5.SlapOSCloud
\ No newline at end of file
master/bt5/slapos_cloud/bt/template_portal_type_type_mixin_list
View file @
9998c6f4
Catalog Tool | SlapOSCatalogToolCacheMixin
Compute Node | SlapOSCacheMixin
Compute Node | SlapOSComputeNodeMixin
Compute Partition | SlapOSCacheMixin
...
...
master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapTool.py
View file @
9998c6f4
...
...
@@ -15,12 +15,13 @@ import xml.dom.ext
import
StringIO
import
difflib
import
hashlib
import
json
from
binascii
import
hexlify
from
OFS.Traversable
import
NotFound
def
hashData
(
data
):
return
hexlify
(
hashlib
.
sha1
(
data
).
digest
())
return
hexlify
(
hashlib
.
sha1
(
json
.
dumps
(
data
,
sort_keys
=
True
)
).
digest
())
class
Simulator
:
...
...
@@ -87,8 +88,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
self
.
commit
()
first_etag
=
self
.
compute_node
.
_calculateRefreshEtag
()
first_body_fingerprint
=
hashData
(
self
.
portal_slap
.
_getSlapComputeNodeXMLFromDict
(
self
.
compute_node
.
_getCacheComputeNodeInformation
(
self
.
compute_node_id
)
)
)
self
.
assertEqual
(
200
,
response
.
status
)
self
.
assertTrue
(
'last-modified'
not
in
response
.
headers
)
self
.
assertEqual
(
first_etag
,
response
.
headers
.
get
(
'etag'
))
...
...
@@ -122,8 +125,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
self
.
assertTrue
(
'last-modified'
not
in
response
.
headers
)
second_etag
=
self
.
compute_node
.
_calculateRefreshEtag
()
second_body_fingerprint
=
hashData
(
self
.
portal_slap
.
_getSlapComputeNodeXMLFromDict
(
self
.
compute_node
.
_getCacheComputeNodeInformation
(
self
.
compute_node_id
)
)
)
self
.
assertNotEqual
(
first_etag
,
second_etag
)
# The indexation timestamp does not impact the response body
self
.
assertEqual
(
first_body_fingerprint
,
second_body_fingerprint
)
...
...
@@ -155,8 +160,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
# Edition does not impact the etag
self
.
assertEqual
(
second_etag
,
self
.
compute_node
.
_calculateRefreshEtag
())
third_body_fingerprint
=
hashData
(
self
.
portal_slap
.
_getSlapComputeNodeXMLFromDict
(
self
.
compute_node
.
_getCacheComputeNodeInformation
(
self
.
compute_node_id
)
)
)
# The edition impacts the response body
self
.
assertNotEqual
(
first_body_fingerprint
,
third_body_fingerprint
)
response
=
self
.
portal_slap
.
getFullComputerInformation
(
self
.
compute_node_id
)
...
...
@@ -194,7 +201,9 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
# The edition does not impact the response body yet, as the aggregate relation
# is not yet unindex
self
.
assertEqual
(
third_body_fingerprint
,
hashData
(
self
.
portal_slap
.
_getSlapComputeNodeXMLFromDict
(
self
.
compute_node
.
_getCacheComputeNodeInformation
(
self
.
compute_node_id
)
)
))
response
=
self
.
portal_slap
.
getFullComputerInformation
(
self
.
compute_node_id
)
self
.
commit
()
...
...
@@ -216,8 +225,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
self
.
assertTrue
(
'last-modified'
not
in
response
.
headers
)
fourth_etag
=
self
.
compute_node
.
_calculateRefreshEtag
()
fourth_body_fingerprint
=
hashData
(
self
.
portal_slap
.
_getSlapComputeNodeXMLFromDict
(
self
.
compute_node
.
_getCacheComputeNodeInformation
(
self
.
compute_node_id
)
)
)
self
.
assertNotEqual
(
third_etag
,
fourth_etag
)
# The indexation timestamp does not impact the response body
self
.
assertNotEqual
(
third_body_fingerprint
,
fourth_body_fingerprint
)
...
...
master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapTool.xml
View file @
9998c6f4
...
...
@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_recorded_property_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
testSlapOSSlapTool
</string>
</value>
...
...
@@ -55,28 +49,13 @@
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
I
=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
...
...
@@ -89,7 +68,7 @@
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
Q
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
</value>
</item>
</dictionary>
...
...
@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record
id=
"
4"
aka=
"AAAAAAAAAAQ
="
>
<record
id=
"
3"
aka=
"AAAAAAAAAAM
="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
...
...
master/bt5/slapos_slap_tool/ToolComponentTemplateItem/portal_components/tool.erp5.SlapTool.py
View file @
9998c6f4
...
...
@@ -28,10 +28,9 @@
#
##############################################################################
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
Unauthorized
from
AccessControl.Permissions
import
access_contents_information
from
AccessControl
import
getSecurityManager
from
Products.ERP5Type.UnrestrictedMethod
import
UnrestrictedMethod
from
OFS.Traversable
import
NotFound
from
Products.DCWorkflow.DCWorkflow
import
ValidationFailed
...
...
@@ -39,10 +38,16 @@ from Products.ERP5Type.Globals import InitializeClass
from
Products.ERP5Type.Tool.BaseTool
import
BaseTool
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type.Cache
import
CachingMethod
from
erp5.component.module.SlapOSCloud
import
_assertACI
from
Products.ERP5Type.Cache
import
DEFAULT_CACHE_SCOPE
from
lxml
import
etree
try
:
from
slapos.slap.slap
import
(
Computer
as
ComputeNode
)
Computer
as
ComputeNode
,
ComputerPartition
as
SlapComputePartition
,
SoftwareInstance
as
SlapSoftwareInstance
,
SoftwareRelease
)
from
slapos.util
import
dict2xml
,
calculate_dict_hash
,
loads
,
dumps
except
ImportError
:
# Do no prevent instance from starting
...
...
@@ -50,6 +55,12 @@ except ImportError:
class
ComputeNode
:
def
__init__
(
self
):
raise
ImportError
class
SlapComputePartition
:
def
__init__
(
self
):
raise
ImportError
class
SoftwareRelease
:
def
__init__
(
self
):
raise
ImportError
def
dict2xml
(
dictionary
):
raise
ImportError
def
calculate_dict_hash
(
dictionary
):
...
...
@@ -58,6 +69,10 @@ except ImportError:
raise
ImportError
def
dumps
(
*
args
):
raise
ImportError
class
SlapSoftwareInstance
:
def
__init__
(
self
):
raise
ImportError
from
zLOG
import
LOG
,
INFO
import
StringIO
...
...
@@ -111,13 +126,6 @@ def castToStr(dict_kw):
xml_declaration
=
True
,
encoding
=
'utf-8'
)
def
_assertACI
(
document
):
sm
=
getSecurityManager
()
if
sm
.
checkPermission
(
access_contents_information
,
document
):
return
document
raise
Unauthorized
(
'User %r has no access to %r'
%
(
sm
.
getUser
(),
document
))
_MARKER
=
object
()
...
...
@@ -163,20 +171,56 @@ class SlapTool(BaseTool):
Reuses slap library for easy marshalling.
"""
user
=
self
.
getPortalObject
().
portal_membership
.
getAuthenticatedMember
().
getUserName
()
portal
=
self
.
getPortalObject
()
user
=
portal
.
portal_membership
.
getAuthenticatedMember
().
getUserName
()
if
str
(
user
)
==
computer_id
:
compute_node
=
self
.
getPortalObject
()
.
portal_membership
.
getAuthenticatedMember
().
getUserValue
()
compute_node
=
portal
.
portal_membership
.
getAuthenticatedMember
().
getUserValue
()
compute_node
.
setAccessStatus
(
computer_id
)
else
:
# Don't use getDocument because we don't want use _assertACI here, but
# just call the API on computer.
compute_node
=
self
.
getPortalObject
()
.
portal_catalog
.
unrestrictedSearchResults
(
compute_node
=
portal
.
portal_catalog
.
unrestrictedSearchResults
(
portal_type
=
'Compute Node'
,
reference
=
computer_id
,
validation_state
=
"validated"
)[
0
].
getObject
()
refresh_etag
=
compute_node
.
_calculateRefreshEtag
()
body
,
etag
=
compute_node
.
_getComputeNodeInformation
(
user
,
refresh_etag
)
# Keep compatibility with older clients that relies on marshalling.
# This code is an adaptation of SlapOSComputeNodeMixin._getComputeNodeInformation
# To comply with cache capability.
user_document
=
_assertACI
(
portal
.
portal_catalog
.
unrestrictedGetResultValue
(
reference
=
user
,
portal_type
=
[
'Person'
,
'Compute Node'
,
'Software Instance'
]))
user_type
=
user_document
.
getPortalType
()
if
user_type
in
(
'Compute Node'
,
'Person'
):
if
not
compute_node
.
_isTestRun
():
cache_plugin
=
compute_node
.
_getCachePlugin
()
key
=
'%s_%s'
%
(
compute_node
.
getReference
(),
user
)
try
:
entry
=
cache_plugin
.
get
(
key
,
DEFAULT_CACHE_SCOPE
)
except
KeyError
:
entry
=
None
if
entry
is
not
None
and
isinstance
(
entry
.
getValue
(),
dict
):
cached_dict
=
entry
.
getValue
()
cached_etag
=
cached_dict
.
get
(
'refresh_etag'
,
None
)
if
(
refresh_etag
!=
cached_etag
):
# Do not recalculate the compute_node information
# if nothing changed
compute_node
.
_activateFillComputeNodeInformationCache
(
user
)
etag
=
cached_etag
body
=
cached_dict
[
'data_xml'
]
else
:
compute_node
.
_activateFillComputeNodeInformationCache
(
user
)
self
.
REQUEST
.
response
.
setStatus
(
503
)
return
self
.
REQUEST
.
response
else
:
computer_dict
,
etag
=
compute_node
.
_getComputeNodeInformation
(
user
,
refresh_etag
)
body
=
self
.
_getSlapComputeNodeXMLFromDict
(
computer_dict
)
else
:
computer_dict
,
etag
=
compute_node
.
_getComputeNodeInformation
(
user
,
refresh_etag
)
body
=
self
.
_getSlapComputeNodeXMLFromDict
(
computer_dict
)
self
.
REQUEST
.
response
.
setHeader
(
'Content-Type'
,
'text/xml; charset=utf-8'
)
if
self
.
REQUEST
.
response
.
getStatus
()
==
200
:
# Keep in cache server for 7 days
self
.
REQUEST
.
response
.
setHeader
(
'Cache-Control'
,
...
...
@@ -275,7 +319,7 @@ class SlapTool(BaseTool):
"""
Get the connection status of the partition
"""
compute_node
=
self
.
_getComputeNodeDocumen
t
(
computer_id
)
compute_node
=
self
.
portal_catalog
.
getComputeNodeObjec
t
(
computer_id
)
data_dict
=
compute_node
.
getAccessStatus
()
# Keep in cache server for 7 days
...
...
@@ -295,7 +339,7 @@ class SlapTool(BaseTool):
"""
Get the connection status of the software installation
"""
compute_node
=
self
.
_getComputeNodeDocumen
t
(
computer_id
)
compute_node
=
self
.
portal_catalog
.
getComputeNodeObjec
t
(
computer_id
)
# Be sure to prevent accessing information to disallowed users
compute_node
=
_assertACI
(
compute_node
)
try
:
...
...
@@ -574,7 +618,7 @@ class SlapTool(BaseTool):
'doc/computer_consumption.xsd'
)
if
self
.
_validateXML
(
use_string
,
compute_node_consumption_model
):
compute_node
=
self
.
_getComputeNodeDocumen
t
(
computer_id
)
compute_node
=
self
.
portal_catalog
.
getComputeNodeObjec
t
(
computer_id
)
tree
=
etree
.
fromstring
(
use_string
)
source_reference
=
\
tree
.
find
(
'transaction'
).
find
(
'reference'
).
text
or
""
...
...
@@ -595,7 +639,7 @@ class SlapTool(BaseTool):
"""
Fire up bung on Compute Node
"""
compute_node
=
self
.
_getComputeNodeDocumen
t
(
compute_node_id
)
compute_node
=
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_id
)
return
compute_node
.
reportComputeNodeBang
(
comment
=
message
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
...
...
@@ -611,13 +655,13 @@ class SlapTool(BaseTool):
def
loadComputerConfigurationFromXML
(
self
,
xml
):
"Load the given xml as configuration for the compute_node object"
compute_node_dict
=
loads
(
xml
)
compute_node
=
self
.
_getComputeNodeDocumen
t
(
compute_node_dict
[
'reference'
])
compute_node
=
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_dict
[
'reference'
])
compute_node
.
ComputeNode_updateFromDict
(
compute_node_dict
)
return
'Content properly posted.'
@
convertToREST
def
_generateComputerCertificate
(
self
,
compute_node_id
):
self
.
_getComputeNodeDocumen
t
(
compute_node_id
).
generateCertificate
()
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_id
).
generateCertificate
()
result
=
{
'certificate'
:
self
.
REQUEST
.
get
(
'compute_node_certificate'
).
decode
(
"UTF-8"
),
'key'
:
self
.
REQUEST
.
get
(
'compute_node_key'
).
decode
(
"UTF-8"
)
...
...
@@ -632,7 +676,7 @@ class SlapTool(BaseTool):
@
convertToREST
def
_revokeComputerCertificate
(
self
,
compute_node_id
):
self
.
_getComputeNodeDocumen
t
(
compute_node_id
).
revokeCertificate
()
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_id
).
revokeCertificate
()
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'revokeComputerCertificate'
)
...
...
@@ -650,10 +694,28 @@ class SlapTool(BaseTool):
"""
# Try to get the compute partition to raise an exception if it doesn't
# exist
compute_partition_document
=
self
.
_getComputePartitionDocumen
t
(
compute_partition_document
=
self
.
getPortalObject
().
portal_catalog
.
getComputePartitionObjec
t
(
computer_reference
,
computer_partition_reference
)
slap_compute_partition
=
compute_partition_document
.
_registerComputePartition
()
partition_dict
=
compute_partition_document
.
_registerComputePartition
()
slap_compute_partition
=
SlapComputePartition
(
partition_id
=
partition_dict
[
"partition_id"
],
computer_id
=
partition_dict
[
'compute_node_id'
]
)
slap_compute_partition
.
_requested_state
=
partition_dict
[
"_requested_state"
]
slap_compute_partition
.
_need_modification
=
partition_dict
[
"_need_modification"
]
if
partition_dict
[
"_software_release_document"
]
is
not
None
:
slap_compute_partition
.
_parameter_dict
=
partition_dict
[
"_parameter_dict"
]
slap_compute_partition
.
_connection_dict
=
partition_dict
[
"_connection_dict"
]
slap_compute_partition
.
_filter_dict
=
partition_dict
[
"_filter_dict"
]
slap_compute_partition
.
_instance_guid
=
partition_dict
[
"_instance_guid"
]
slap_compute_partition
.
_software_release_document
=
SoftwareRelease
(
software_release
=
partition_dict
[
"_software_release_document"
][
"software_release"
],
computer_guid
=
partition_dict
[
"_software_release_document"
][
"computer_guid"
])
slap_compute_partition
.
_synced
=
partition_dict
[
"_synced"
]
else
:
slap_compute_partition
.
_software_release_document
=
None
# Keep in cache server for 7 days
self
.
REQUEST
.
response
.
setStatus
(
200
)
...
...
@@ -670,7 +732,6 @@ class SlapTool(BaseTool):
####################################################
# Internal methods
####################################################
def
_validateXML
(
self
,
to_be_validated
,
xsd_model
):
"""Will validate the xml file"""
#We parse the XSD model
...
...
@@ -698,7 +759,7 @@ class SlapTool(BaseTool):
"""
Request Software Release installation
"""
compute_node_document
=
self
.
_getComputeNodeDocumen
t
(
compute_node_id
)
compute_node_document
=
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_id
)
compute_node_document
.
requestSoftwareRelease
(
software_release_url
=
url
,
state
=
state
)
@
convertToREST
...
...
@@ -706,7 +767,7 @@ class SlapTool(BaseTool):
"""
Log the software release status
"""
compute_node
=
self
.
_getComputeNodeDocumen
t
(
compute_node_id
)
compute_node
=
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_id
)
software_installation
=
compute_node
.
_getSoftwareInstallationFromUrl
(
url
)
software_installation
.
setBuildingStatus
(
'software release %s'
%
url
,
"building"
)
...
...
@@ -716,7 +777,7 @@ class SlapTool(BaseTool):
"""
Log the software release status
"""
compute_node
=
self
.
_getComputeNodeDocumen
t
(
compute_node_id
)
compute_node
=
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_id
)
software_installation
=
compute_node
.
_getSoftwareInstallationFromUrl
(
url
)
software_installation
.
setAccessStatus
(
'software release %s available'
%
url
,
"available"
)
...
...
@@ -726,7 +787,7 @@ class SlapTool(BaseTool):
"""
Reports that Software Release is destroyed
"""
compute_node
=
self
.
_getComputeNodeDocumen
t
(
compute_node_id
)
compute_node
=
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_id
)
software_installation
=
compute_node
.
_getSoftwareInstallationFromUrl
(
url
)
if
software_installation
.
getSlapState
()
!=
'destroy_requested'
:
raise
NotFound
...
...
@@ -923,7 +984,8 @@ class SlapTool(BaseTool):
if
not
requested_software_instance
.
getAggregate
(
portal_type
=
"Compute Partition"
):
raise
SoftwareInstanceNotReady
else
:
return
dumps
(
requested_software_instance
.
_asSoftwareInstance
())
return
dumps
(
SlapSoftwareInstance
(
**
requested_software_instance
.
_asSoftwareInstanceDict
()))
@
UnrestrictedMethod
def
_updateComputePartitionRelatedInstanceList
(
self
,
compute_node_id
,
...
...
@@ -947,92 +1009,56 @@ class SlapTool(BaseTool):
# Internals methods
####################################################
def
_getDocument
(
self
,
**
kwargs
):
# No need to get all results if an error is raised when at least 2 objects
# are found
l
=
self
.
getPortalObject
().
portal_catalog
.
unrestrictedSearchResults
(
limit
=
2
,
**
kwargs
)
if
len
(
l
)
!=
1
:
raise
NotFound
,
"No document found with parameters: %s"
%
kwargs
def
_getSlapComputeNodeXMLFromDict
(
self
,
computer_dict
):
slap_compute_node
=
ComputeNode
(
computer_dict
[
"_computer_id"
])
slap_compute_node
.
_computer_partition_list
=
[]
slap_compute_node
.
_software_release_list
=
[]
for
partition_dict
in
computer_dict
[
"_computer_partition_list"
]:
slap_compute_partition
=
SlapComputePartition
(
partition_id
=
partition_dict
[
"partition_id"
],
computer_id
=
partition_dict
[
'compute_node_id'
]
)
slap_compute_partition
.
_requested_state
=
partition_dict
[
"_requested_state"
]
slap_compute_partition
.
_need_modification
=
partition_dict
[
"_need_modification"
]
if
partition_dict
[
"_software_release_document"
]
is
not
None
:
slap_compute_partition
.
_access_status
=
partition_dict
[
"_access_status"
]
slap_compute_partition
.
_parameter_dict
=
partition_dict
[
"_parameter_dict"
]
slap_compute_partition
.
_connection_dict
=
partition_dict
[
"_connection_dict"
]
slap_compute_partition
.
_filter_dict
=
partition_dict
[
"_filter_dict"
]
slap_compute_partition
.
_instance_guid
=
partition_dict
[
"_instance_guid"
]
slap_compute_partition
.
_software_release_document
=
SoftwareRelease
(
software_release
=
partition_dict
[
"_software_release_document"
][
"software_release"
],
computer_guid
=
partition_dict
[
"_software_release_document"
][
"computer_guid"
])
else
:
return
_assertACI
(
l
[
0
].
getObject
())
slap_compute_partition
.
_software_release_document
=
None
def
_getNonCachedComputeNodeDocument
(
self
,
compute_node_reference
):
return
self
.
_getDocument
(
portal_type
=
'Compute Node'
,
# XXX Hardcoded validation state
validation_state
=
"validated"
,
reference
=
compute_node_reference
).
getRelativeUrl
()
slap_compute_node
.
_computer_partition_list
.
append
(
slap_compute_partition
)
def
_getComputeNodeDocument
(
self
,
compute_node_reference
):
"""
Get the validated compute_node with this reference.
"""
result
=
CachingMethod
(
self
.
_getNonCachedComputeNodeDocument
,
id
=
'_getComputeNodeDocument'
,
cache_factory
=
'slap_cache_factory'
)(
compute_node_reference
)
return
self
.
getPortalObject
().
restrictedTraverse
(
result
)
for
software_release_dict
in
computer_dict
[
'_software_release_list'
]:
slap_software_release
=
SoftwareRelease
(
software_release
=
software_release_dict
[
"software_release"
],
computer_guid
=
software_release_dict
[
'computer_guid'
])
slap_software_release
.
_requested_state
=
software_release_dict
[
'_requested_state'
]
slap_software_release
.
_known_state
=
software_release_dict
[
'_known_state'
]
slap_compute_node
.
_software_release_list
.
append
(
slap_software_release
)
@
UnrestrictedMethod
def
_getComputeNodeUidByReference
(
self
,
compute_node_reference
):
"""
Get the validated compute_node with this reference.
"""
result
=
CachingMethod
(
self
.
_getNonCachedComputeNodeUidByReference
,
id
=
'_getNonCachedComputeNodeUidByReference'
,
cache_factory
=
'slap_cache_factory'
)(
compute_node_reference
)
return
result
@
UnrestrictedMethod
def
_getNonCachedComputeNodeUidByReference
(
self
,
compute_node_reference
):
return
self
.
getPortalObject
().
portal_catalog
.
unrestrictedSearchResults
(
portal_type
=
'Compute Node'
,
reference
=
compute_node_reference
,
validation_state
=
"validated"
)[
0
].
UID
def
_getComputePartitionDocument
(
self
,
compute_node_reference
,
compute_partition_reference
):
"""
Get the compute partition defined in an available compute_node
"""
# Related key might be nice
return
self
.
_getDocument
(
portal_type
=
'Compute Partition'
,
reference
=
compute_partition_reference
,
parent_uid
=
self
.
_getComputeNodeUidByReference
(
compute_node_reference
))
return
dumps
(
slap_compute_node
)
def
_getSoftwareInstanceForComputePartition
(
self
,
compute_node_id
,
compute_partition_id
,
slave_reference
=
None
):
compute_partition_document
=
self
.
_getComputePartitionDocument
(
compute_node_id
,
compute_partition_id
)
if
compute_partition_document
.
getSlapState
()
!=
'busy'
:
LOG
(
'SlapTool::_getSoftwareInstanceForComputePartition'
,
INFO
,
'Compute partition %s shall be busy, is free'
%
compute_partition_document
.
getRelativeUrl
())
raise
NotFound
,
"No software instance found for: %s - %s"
%
(
compute_node_id
,
compute_partition_id
)
else
:
query_kw
=
{
'validation_state'
:
'validated'
,
'portal_type'
:
'Slave Instance'
,
'default_aggregate_uid'
:
compute_partition_document
.
getUid
(),
}
if
slave_reference
is
None
:
query_kw
[
'portal_type'
]
=
"Software Instance"
else
:
query_kw
[
'reference'
]
=
slave_reference
software_instance
=
_assertACI
(
self
.
getPortalObject
().
portal_catalog
.
unrestrictedGetResultValue
(
**
query_kw
))
if
software_instance
is
None
:
raise
NotFound
,
"No software instance found for: %s - %s"
%
(
compute_partition_document
=
self
.
getPortalObject
().
portal_catalog
.
getComputePartitionObject
(
compute_node_id
,
compute_partition_id
)
else
:
return
software_instance
return
compute_partition_document
.
_getSoftwareInstance
(
slave_reference
)
@
convertToREST
def
_softwareReleaseError
(
self
,
url
,
compute_node_id
,
error_log
):
"""
Log the compute_node status
"""
compute_node
=
self
.
_getComputeNodeDocumen
t
(
compute_node_id
)
compute_node
=
self
.
getPortalObject
().
portal_catalog
.
getComputeNodeObjec
t
(
compute_node_id
)
software_installation
=
compute_node
.
_getSoftwareInstallationFromUrl
(
url
)
software_installation
.
setErrorStatus
(
'while installing %s'
%
url
)
...
...
master/bt5/slapos_slap_tool/ToolComponentTemplateItem/portal_components/tool.erp5.SlapTool.xml
View file @
9998c6f4
...
...
@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_recorded_property_dict
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
SlapTool
</string>
</value>
...
...
@@ -55,28 +49,13 @@
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
I
=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
...
...
@@ -89,7 +68,7 @@
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
Q
=
</string>
</persistent>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAA
M
=
</string>
</persistent>
</value>
</item>
</dictionary>
...
...
@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record
id=
"
4"
aka=
"AAAAAAAAAAQ
="
>
<record
id=
"
3"
aka=
"AAAAAAAAAAM
="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
...
...
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