Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
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
Paul Graydon
erp5
Commits
c281ca18
Commit
c281ca18
authored
Aug 06, 2019
by
Rafael Monnerat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5.util: Update the SlapOS API
The API changed on the slap, this commit follow up the changes.
parent
c5e2f481
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
33 additions
and
120 deletions
+33
-120
erp5/util/testnode/SlapOSMasterCommunicator.py
erp5/util/testnode/SlapOSMasterCommunicator.py
+33
-120
No files found.
erp5/util/testnode/SlapOSMasterCommunicator.py
View file @
c281ca18
...
@@ -10,6 +10,8 @@ from uritemplate import expand
...
@@ -10,6 +10,8 @@ from uritemplate import expand
import
slapos.slap
import
slapos.slap
from
slapos.slap
import
SoftwareProductCollection
from
slapos.slap
import
SoftwareProductCollection
from
slapos.client
import
SOFTWARE_PRODUCT_NAMESPACE
from
slapos.slap.util
import
xml2dict
from
requests.exceptions
import
HTTPError
from
requests.exceptions
import
HTTPError
from
..taskdistribution
import
SAFE_RPC_EXCEPTION_LIST
from
..taskdistribution
import
SAFE_RPC_EXCEPTION_LIST
from
.
import
logger
from
.
import
logger
...
@@ -19,8 +21,6 @@ import six
...
@@ -19,8 +21,6 @@ import six
# max time to instance changing state: 3 hour
# max time to instance changing state: 3 hour
MAX_INSTANCE_TIME
=
60
*
60
*
3
MAX_INSTANCE_TIME
=
60
*
60
*
3
SOFTWARE_PRODUCT_NAMESPACE
=
"product."
SOFTWARE_STATE_UNKNOWN
=
"SOFTWARE_STATE_UNKNOWN"
SOFTWARE_STATE_UNKNOWN
=
"SOFTWARE_STATE_UNKNOWN"
SOFTWARE_STATE_INSTALLING
=
"SOFTWARE_STATE_INSTALLING"
SOFTWARE_STATE_INSTALLING
=
"SOFTWARE_STATE_INSTALLING"
SOFTWARE_STATE_INSTALLED
=
"SOFTWARE_STATE_INSTALLED"
SOFTWARE_STATE_INSTALLED
=
"SOFTWARE_STATE_INSTALLED"
...
@@ -83,6 +83,10 @@ class SlapOSMasterCommunicator(object):
...
@@ -83,6 +83,10 @@ class SlapOSMasterCommunicator(object):
self
.
url
=
url
self
.
url
=
url
#########################################################
# Wrapper functions to support network retries
#########################################################
@
retryOnNetworkFailure
@
retryOnNetworkFailure
def
_supply
(
self
,
state
=
"available"
):
def
_supply
(
self
,
state
=
"available"
):
if
self
.
computer_guid
is
None
:
if
self
.
computer_guid
is
None
:
...
@@ -113,126 +117,35 @@ class SlapOSMasterCommunicator(object):
...
@@ -113,126 +117,35 @@ class SlapOSMasterCommunicator(object):
state
=
state
,
state
=
state
,
**
self
.
request_kw
)
**
self
.
request_kw
)
@
retryOnNetworkFailure
def
isInstanceRequested
(
self
,
instance_title
):
def
isInstanceRequested
(
self
,
instance_title
):
hateoas
=
getattr
(
self
.
slap
,
'_hateoas_navigator'
,
None
)
return
len
(
self
.
hateoas_navigator
.
_getHostingSubscriptionList
(
return
instance_title
in
hateoas
.
getHostingSubscriptionDict
(
)
title
=
instance_title
)
)
@
retryOnNetworkFailure
@
retryOnNetworkFailure
def
_hateoas_getComputer
(
self
,
reference
):
def
getComputer
(
self
,
reference
):
root_document
=
self
.
hateoas_navigator
.
getRootDocument
()
return
self
.
hateoas_navigator
.
getComputer
(
reference
)
search_url
=
root_document
[
"_links"
][
'raw_search'
][
'href'
]
getter_link
=
expand
(
search_url
,
{
"query"
:
"reference:%s AND portal_type:Computer"
%
reference
,
"select_list"
:
[
"relative_url"
],
"limit"
:
1
})
result
=
self
.
hateoas_navigator
.
GET
(
getter_link
)
content_list
=
json
.
loads
(
result
)[
'_embedded'
][
'contents'
]
if
len
(
content_list
)
==
0
:
raise
Exception
(
'No Computer found.'
)
computer_relative_url
=
content_list
[
0
][
"relative_url"
]
getter_url
=
self
.
hateoas_navigator
.
getDocumentAndHateoas
(
computer_relative_url
)
return
json
.
loads
(
self
.
hateoas_navigator
.
GET
(
getter_url
))
@
retryOnNetworkFailure
@
retryOnNetworkFailure
def
getSoftwareInstallationList
(
self
,
computer_guid
=
None
):
def
getSoftwareInstallationList
(
self
,
computer_guid
=
None
):
# XXX Move me to slap.py API
return
self
.
hateoas_navigator
.
getSoftwareInstallationList
(
computer_guid
=
computer_guid
)
computer
=
self
.
_hateoas_getComputer
(
computer_guid
)
if
computer_guid
else
self
.
_hateoas_getComputer
(
self
.
computer_guid
)
# Not a list ?
action
=
computer
[
'_links'
][
'action_object_slap'
]
if
action
.
get
(
'title'
)
==
'getHateoasSoftwareInstallationList'
:
getter_link
=
action
[
'href'
]
else
:
raise
Exception
(
'No Link found found.'
)
result
=
self
.
hateoas_navigator
.
GET
(
getter_link
)
return
json
.
loads
(
result
)[
'_links'
][
'content'
]
@
retryOnNetworkFailure
def
getSoftwareInstallationNews
(
self
,
computer_guid
=
None
):
getter_link
=
None
for
si
in
self
.
getSoftwareInstallationList
(
computer_guid
):
if
si
[
"title"
]
==
self
.
url
:
getter_link
=
si
[
"href"
]
break
# We could not find the document, so it is probably too soon.
if
getter_link
is
None
:
return
""
result
=
self
.
hateoas_navigator
.
GET
(
getter_link
)
action_object_slap_list
=
json
.
loads
(
result
)[
'_links'
][
'action_object_slap'
]
for
action
in
action_object_slap_list
:
if
action
.
get
(
'title'
)
==
'getHateoasNews'
:
getter_link
=
action
[
'href'
]
break
else
:
raise
Exception
(
'getHateoasNews not found.'
)
result
=
self
.
hateoas_navigator
.
GET
(
getter_link
)
if
len
(
json
.
loads
(
result
)[
'news'
])
>
0
:
return
json
.
loads
(
result
)[
'news'
][
0
][
"text"
]
return
""
@
retryOnNetworkFailure
@
retryOnNetworkFailure
def
getInstanceUrlList
(
self
):
def
getInstanceUrlList
(
self
):
hosting_subscription_dict
=
self
.
hateoas_navigator
.
_hateoas_getHostingSubscriptionDict
()
return
self
.
hateoas_navigator
.
getHostingSubscriptionInstanceList
(
# Don't store hosting subscription url. It changes from time to time.
self
.
title
)
hosting_subscription_url
=
None
for
hs
in
hosting_subscription_dict
:
if
hs
[
'title'
]
==
self
.
name
:
hosting_subscription_url
=
hs
[
'href'
]
break
if
hosting_subscription_url
is
None
:
return
None
return
self
.
hateoas_navigator
.
getHateoasInstanceList
(
hosting_subscription_url
)
@
retryOnNetworkFailure
def
getNewsFromInstance
(
self
,
url
):
result
=
self
.
hateoas_navigator
.
GET
(
url
)
result
=
json
.
loads
(
result
)
if
result
[
'_links'
].
get
(
'action_object_slap'
,
None
)
is
None
:
return
None
object_link
=
self
.
hateoas_navigator
.
hateoasGetLinkFromLinks
(
result
[
'_links'
][
'action_object_slap'
],
'getHateoasNews'
)
result
=
self
.
hateoas_navigator
.
GET
(
object_link
)
return
json
.
loads
(
result
)[
'news'
]
@
retryOnNetworkFailure
@
retryOnNetworkFailure
def
getInformationFromInstance
(
self
,
url
):
def
getInformationFromInstance
(
self
,
url
):
result
=
self
.
hateoas_navigator
.
GET
(
url
)
return
self
.
hateoas_navigator
.
jio_get
(
url
)
result
=
json
.
loads
(
result
)
if
result
[
'_links'
].
get
(
'action_object_slap'
,
None
)
is
None
:
print
(
result
[
'links'
])
return
None
object_link
=
self
.
hateoas_navigator
.
hateoasGetLinkFromLinks
(
result
[
'_links'
][
'action_object_slap'
],
'getHateoasInformation'
)
result
=
self
.
hateoas_navigator
.
GET
(
object_link
)
return
json
.
loads
(
result
)
@
retryOnNetworkFailure
def
_getSoftwareState
(
self
,
computer_guid
=
None
):
def
_getSoftwareState
(
self
,
computer_guid
=
None
):
if
self
.
computer_guid
is
None
:
if
self
.
computer_guid
is
None
:
return
SOFTWARE_STATE_INSTALLED
return
SOFTWARE_STATE_INSTALLED
message
=
self
.
getSoftwareInstallationNews
(
computer_guid
)
message
=
self
.
hateoas_navigator
.
getSoftwareInstallationNews
(
computer_guid
=
computer_guid
,
self
.
url
)
logger
.
info
(
message
)
logger
.
info
(
message
)
if
message
.
startswith
(
"#error no data found"
):
if
message
.
startswith
(
"#error no data found"
):
return
SOFTWARE_STATE_UNKNOWN
return
SOFTWARE_STATE_UNKNOWN
...
@@ -270,19 +183,18 @@ class SlapOSMasterCommunicator(object):
...
@@ -270,19 +183,18 @@ class SlapOSMasterCommunicator(object):
message_list
=
[]
message_list
=
[]
try
:
try
:
for
instance
in
self
.
getInstanceUrlList
():
for
instance
in
self
.
getInstanceUrlList
():
news
=
self
.
getNewsFromInstance
(
instance
[
"href"
])
news
=
instance
[
'SoftwareInstance_getNewsDict'
]
information
=
self
.
getInformationFromInstance
(
instance
[
"href"
])
state
=
INSTANCE_STATE_UNKNOWN
state
=
INSTANCE_STATE_UNKNOWN
monitor_information_dict
=
{}
monitor_information_dict
=
{}
info_created_at
=
"-1"
info_created_at
=
"-1"
is_slave
=
in
formation
[
'slave'
]
is_slave
=
in
stance
[
'portal_type'
]
==
"Slave Instance"
if
is_slave
:
if
is_slave
:
if
(
information
[
"connection_dict"
])
>
0
:
if
len
(
instance
[
'getConnectionXmlAsDict'
])
>
0
:
state
=
INSTANCE_STATE_STARTED
state
=
INSTANCE_STATE_STARTED
else
:
else
:
# not slave
# not slave
instance_state
=
news
[
0
]
instance_state
=
news
if
instance_state
.
get
(
'created_at'
,
'-1'
)
!=
"-1"
:
if
instance_state
.
get
(
'created_at'
,
'-1'
)
!=
"-1"
:
# the following does NOT take TZ into account
# the following does NOT take TZ into account
created_at
=
datetime
.
datetime
.
strptime
(
instance_state
[
'created_at'
],
created_at
=
datetime
.
datetime
.
strptime
(
instance_state
[
'created_at'
],
...
@@ -306,7 +218,7 @@ class SlapOSMasterCommunicator(object):
...
@@ -306,7 +218,7 @@ class SlapOSMasterCommunicator(object):
if
state
==
INSTANCE_STATE_STARTED_WITH_ERROR
:
if
state
==
INSTANCE_STATE_STARTED_WITH_ERROR
:
# search for monitor url
# search for monitor url
monitor_v6_url
=
in
formation
[
"connection_dict"
].
get
(
"monitor_v6_url"
)
monitor_v6_url
=
in
stance
[
'getConnectionXmlAsDict'
].
get
(
"monitor_v6_url"
)
try
:
try
:
monitor_information_dict
=
self
.
getRSSEntryFromMonitoring
(
monitor_v6_url
)
monitor_information_dict
=
self
.
getRSSEntryFromMonitoring
(
monitor_v6_url
)
except
Exception
:
except
Exception
:
...
@@ -314,11 +226,13 @@ class SlapOSMasterCommunicator(object):
...
@@ -314,11 +226,13 @@ class SlapOSMasterCommunicator(object):
logger
.
error
(
traceback
.
format_exc
())
logger
.
error
(
traceback
.
format_exc
())
monitor_information_dict
=
{
"message"
:
"Unable to download"
}
monitor_information_dict
=
{
"message"
:
"Unable to download"
}
instance
[
"connection_dict"
]
=
instance
[
"getConnectionXmlAsDict"
]
instance
[
"parameter_dict"
]
=
xml2dict
(
instance
[
"text_content"
]))
message_list
.
append
({
message_list
.
append
({
'title'
:
instance
[
"title"
],
'title'
:
instance
[
"title"
],
'slave'
:
is_slave
,
'slave'
:
is_slave
,
'news'
:
news
[
0
]
,
'news'
:
news
,
'information'
:
in
formation
,
'information'
:
in
stance
,
'monitor'
:
monitor_information_dict
,
'monitor'
:
monitor_information_dict
,
'state'
:
state
'state'
:
state
})
})
...
@@ -456,8 +370,7 @@ class SlapOSTester(SlapOSMasterCommunicator):
...
@@ -456,8 +370,7 @@ class SlapOSTester(SlapOSMasterCommunicator):
for
instance
in
self
.
getInstanceUrlList
():
for
instance
in
self
.
getInstanceUrlList
():
if
instance
[
"title"
]
==
"Monitor Frontend apache-frontend-1"
:
if
instance
[
"title"
]
==
"Monitor Frontend apache-frontend-1"
:
try
:
try
:
information
=
self
.
getInformationFromInstance
(
instance
[
"href"
])
frontend_master_ipv6
=
xml2dict
(
instance
[
'text_content'
])[
'url'
]
frontend_master_ipv6
=
information
[
'parameter_dict'
][
'url'
]
except
Exception
as
e
:
except
Exception
as
e
:
pass
pass
start_time
=
time
.
time
()
start_time
=
time
.
time
()
...
@@ -471,18 +384,17 @@ class SlapOSTester(SlapOSMasterCommunicator):
...
@@ -471,18 +384,17 @@ class SlapOSTester(SlapOSMasterCommunicator):
def
getInstanceUrlDict
(
self
):
def
getInstanceUrlDict
(
self
):
frontend_url_list
=
[]
frontend_url_list
=
[]
for
instance
in
self
.
getInstanceUrlList
():
for
instance
in
self
.
getInstanceUrlList
():
information
=
self
.
getInformationFromInstance
(
instance
[
"href"
])
if
"frontend-"
in
instance
[
"title"
]:
if
"frontend-"
in
instance
[
"title"
]:
try
:
try
:
frontend
=
[
instance
[
"title"
].
replace
(
"frontend-"
,
""
),
frontend
=
[
instance
[
"title"
].
replace
(
"frontend-"
,
""
),
in
formation
[
"connection_d
ict"
][
"secure_access"
]]
in
stance
[
"getConnectionXmlAsD
ict"
][
"secure_access"
]]
frontend_url_list
.
append
(
frontend
)
frontend_url_list
.
append
(
frontend
)
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
info
(
"Frontend url not generated yet for instance: "
+
instance
[
"title"
])
logger
.
info
(
"Frontend url not generated yet for instance: "
+
instance
[
"title"
])
pass
pass
if
instance
[
"title"
]
==
self
.
name
:
if
instance
[
"title"
]
==
self
.
name
:
try
:
try
:
connection_json
=
json
.
loads
(
in
formation
[
"connection_d
ict"
][
"_"
])
connection_json
=
json
.
loads
(
in
stance
[
"getConnectionXmlAsD
ict"
][
"_"
])
user
=
connection_json
[
"inituser-login"
]
user
=
connection_json
[
"inituser-login"
]
password
=
connection_json
[
"inituser-password"
]
password
=
connection_json
[
"inituser-password"
]
except
Exception
as
e
:
except
Exception
as
e
:
...
@@ -491,8 +403,9 @@ class SlapOSTester(SlapOSMasterCommunicator):
...
@@ -491,8 +403,9 @@ class SlapOSTester(SlapOSMasterCommunicator):
def
destroyInstance
(
self
,
instance_title
):
def
destroyInstance
(
self
,
instance_title
):
self
.
name
=
instance_title
self
.
name
=
instance_title
if
self
.
getInstanceUrlList
():
instance_url_list
=
self
.
InstanceUrlList
()
for
instance
in
self
.
getInstanceUrlList
():
if
instance_url_list
:
for
instance
in
instance_url_list
:
if
instance
[
"title"
]
!=
instance_title
:
if
instance
[
"title"
]
!=
instance_title
:
self
.
_request
(
INSTANCE_STATE_DESTROYED
,
instance
[
"title"
])
self
.
_request
(
INSTANCE_STATE_DESTROYED
,
instance
[
"title"
])
else
:
else
:
...
...
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