Commit e0f418c8 authored by Joanne Hugé's avatar Joanne Hugé

software/ors-amarisoft: use promises from slapos.toolbox

parent a1984961
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
[template] [template]
filename = instance.cfg filename = instance.cfg
md5sum = 270f738ca2ed4438868d97a0fb05269e md5sum = d21dcca80b710df5ab459bd74edd0ac7
[amarisoft-stats.jinja2.py] [amarisoft-stats.jinja2.py]
_update_hash_filename_ = amarisoft-stats.jinja2.py _update_hash_filename_ = amarisoft-stats.jinja2.py
...@@ -28,35 +28,35 @@ md5sum = 39e191080722ac13ebc56b1e6350eb8f ...@@ -28,35 +28,35 @@ md5sum = 39e191080722ac13ebc56b1e6350eb8f
[template-lte-enb-epc] [template-lte-enb-epc]
_update_hash_filename_ = instance-enb-epc.jinja2.cfg _update_hash_filename_ = instance-enb-epc.jinja2.cfg
md5sum = 833667743c693b8d5f78a2527b275a9e md5sum = bb4435f433e100fede09ff921d42c927
[template-lte-enb] [template-lte-enb]
_update_hash_filename_ = instance-enb.jinja2.cfg _update_hash_filename_ = instance-enb.jinja2.cfg
md5sum = acb7eccc4f44b7a1a1bcb8d1decb76a9 md5sum = 9ccb99150a220a40158bb079691c83b8
[template-lte-gnb-epc] [template-lte-gnb-epc]
_update_hash_filename_ = instance-gnb-epc.jinja2.cfg _update_hash_filename_ = instance-gnb-epc.jinja2.cfg
md5sum = 1f0b18cb6d70466d002b378bb931e7da md5sum = 9a0e36188b23831bec3cb53b226baa66
[template-lte-epc] [template-lte-epc]
_update_hash_filename_ = instance-epc.jinja2.cfg _update_hash_filename_ = instance-epc.jinja2.cfg
md5sum = 99c05a34678adb5a70aa64ecf2ee4e35 md5sum = acc9176fd9abe1d04c60a08cdd520eee
[template-lte-gnb] [template-lte-gnb]
_update_hash_filename_ = instance-gnb.jinja2.cfg _update_hash_filename_ = instance-gnb.jinja2.cfg
md5sum = e067a332ab1d6375049b413d90b7fa08 md5sum = 1d161902801a6ac0c461dffdf78e98ac
[template-lte-mme] [template-lte-mme]
_update_hash_filename_ = instance-mme.jinja2.cfg _update_hash_filename_ = instance-mme.jinja2.cfg
md5sum = 9a26877e326bffd57e17320de0d12c6d md5sum = 400accb9d5bc104b1b122a7b9bc3a261
[template-lte-ue-lte] [template-lte-ue-lte]
_update_hash_filename_ = instance-ue-lte.jinja2.cfg _update_hash_filename_ = instance-ue-lte.jinja2.cfg
md5sum = 691a6223e587b6abf1de279375217744 md5sum = 5c1f78588a0d7447807c10765552a6e7
[template-lte-ue-nr] [template-lte-ue-nr]
_update_hash_filename_ = instance-ue-nr.jinja2.cfg _update_hash_filename_ = instance-ue-nr.jinja2.cfg
md5sum = ebc9a8edd23b10c2618bd02d1de76007 md5sum = 5b032c3c9dbbd5b8552b0ebd8dcc9acf
[ue_db.jinja2.cfg] [ue_db.jinja2.cfg]
filename = config/ue_db.jinja2.cfg filename = config/ue_db.jinja2.cfg
...@@ -93,31 +93,3 @@ md5sum = 31c166f0a1b6d664f92b8f318b233d9a ...@@ -93,31 +93,3 @@ md5sum = 31c166f0a1b6d664f92b8f318b233d9a
[ue-nr.jinja2.cfg] [ue-nr.jinja2.cfg]
filename = config/ue-nr.jinja2.cfg filename = config/ue-nr.jinja2.cfg
md5sum = b3078deab008d7e81ddd88ac02b8b698 md5sum = b3078deab008d7e81ddd88ac02b8b698
[sdr-busy-promise]
_update_hash_filename_ = promise/check_sdr_busy.py
md5sum = b0c65aefa60a9d5b9f7e7b38383db48b
[cell-gain-saturated-promise]
_update_hash_filename_ = promise/check_cell_gain_saturated.py
md5sum = 764ca8913ea40964382848cf3233c1f7
[rx-saturated-promise]
_update_hash_filename_ = promise/check_rx_saturated.py
md5sum = 40cf5389fd91845f4426ef159fb20fc0
[baseband-latency-promise]
_update_hash_filename_ = promise/check_baseband_latency.py
md5sum = 4f115e2d9bde9f268c77264dc0deb2a3
[amarisoft-stats-log-promise]
_update_hash_filename_ = promise/check_amarisoft_stats_log.py
md5sum = 5bf57a9074ea5b054d999789cbbe2c87
[cpu-temperature-promise]
_update_hash_filename_ = promise/check_cpu_temperature.py
md5sum = 6812310b65c2d95815afc2b034a5f90f
[interface-up-promise]
_update_hash_filename_ = promise/check_interface_up.py
md5sum = 44ae5693f62b7a4dbc98f700f68d8600
...@@ -14,7 +14,7 @@ parts = ...@@ -14,7 +14,7 @@ parts =
directory directory
lte-enb-request lte-enb-request
lte-mme-request lte-mme-request
cpu-temperature-promise check-cpu-temperature.py
publish-connection-information publish-connection-information
{% for part in part_list -%} {% for part in part_list -%}
{{ ' %s' % part }} {{ ' %s' % part }}
...@@ -87,17 +87,19 @@ return = monitor-base-url ...@@ -87,17 +87,19 @@ return = monitor-base-url
lte-mme-request = ${lte-mme-request:connection-monitor-base-url} lte-mme-request = ${lte-mme-request:connection-monitor-base-url}
lte-enb-request = ${lte-enb-request:connection-monitor-base-url} lte-enb-request = ${lte-enb-request:connection-monitor-base-url}
[cpu-temperature-promise] [macro.promise]
recipe = slapos.cookbook:promise.plugin <= monitor-promise-base
eggs = name = ${:_buildout_section_name_}
slapos.core
python-dateutil [check-cpu-temperature.py]
file = {{ cpu_temperature_promise }} <= macro.promise
output = ${directory:plugins}/check-cpu-temperature.py promise = check_cpu_temperature
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-max-temp = {{ slapparameter_dict.get("promise_cpu_temperature_threshold", 90) }} config-frequency = {{ slapparameter_dict.get("promise_cpu_temperature_frequency", 5) }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold", 80) }} config-max-spot-temp = {{ slapparameter_dict.get("promise_cpu_max_spot_temp", 90) }}
config-max-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold_duration", 600) }} config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_max_avg_temp", 80) }}
config-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temp_duration", 600) }}
config-avg-flag-file = ${directory:var}/promise_cpu_avg_flag_file
[publish-connection-information] [publish-connection-information]
recipe = slapos.cookbook:publish.serialised recipe = slapos.cookbook:publish.serialised
......
...@@ -154,20 +154,20 @@ ...@@ -154,20 +154,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -5,18 +5,16 @@ parts = ...@@ -5,18 +5,16 @@ parts =
lte-enb-config lte-enb-config
lte-enb-service lte-enb-service
amarisoft-stats-service amarisoft-stats-service
sdr-busy-promise
cell-gain-saturated-promise
rx-saturated-promise
baseband-latency-promise
amarisoft-stats-log-promise
{% if slapparameter_dict.get('rrh', '') == "Lopcomm ORAN" %} {% if slapparameter_dict.get('rrh', '') == "Lopcomm ORAN" %}
lopcomm-rrh-stats-service lopcomm-rrh-stats-service
vswr-promise check-lopcomm-vswr.py
{% endif %} {% endif %}
{% if not slapparameter_dict.get("sub-instance", False) %} {% if not slapparameter_dict.get("sub-instance", False) %}
cpu-temperature-promise check-cpu-temperature.py
{% endif %} {% endif %}
check-sdr-busy.py
check-baseband-latency.py
check-amarisoft-stats-log.py
monitor-base monitor-base
publish-connection-information publish-connection-information
...@@ -99,7 +97,6 @@ inline = ...@@ -99,7 +97,6 @@ inline =
{{ enb }}/lteenb ${directory:etc}/enb.cfg >> ${:enb-log} 2>> ${:enb-log}; {{ enb }}/lteenb ${directory:etc}/enb.cfg >> ${:enb-log} 2>> ${:enb-log};
{% endif %} {% endif %}
### eNodeB (enb)
[lte-enb-service] [lte-enb-service]
recipe = slapos.cookbook:wrapper recipe = slapos.cookbook:wrapper
init = ${ltelogs:output} ${directory:log}/enb.log; sleep 2 init = ${ltelogs:output} ${directory:log}/enb.log; sleep 2
...@@ -195,78 +192,53 @@ monitor-title = {{ slapparameter_dict['name'] | string }} ...@@ -195,78 +192,53 @@ monitor-title = {{ slapparameter_dict['name'] | string }}
password = {{ slapparameter_dict['monitor-password'] | string }} password = {{ slapparameter_dict['monitor-password'] | string }}
{% endif %} {% endif %}
[sdr-busy-promise] [macro.promise]
recipe = slapos.cookbook:promise.plugin <= monitor-promise-base
eggs = slapos.core name = ${:_buildout_section_name_}
file = {{ sdr_busy_promise }}
output = ${directory:plugins}/check-sdr-busy.py [check-cpu-temperature.py]
<= macro.promise
promise = check_cpu_temperature
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-frequency = {{ slapparameter_dict.get("promise_cpu_temperature_frequency", 5) }}
config-max-spot-temp = {{ slapparameter_dict.get("promise_cpu_max_spot_temp", 90) }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_max_avg_temp", 80) }}
config-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temp_duration", 600) }}
config-avg-flag-file = ${directory:var}/promise_cpu_avg_flag_file
[check-sdr-busy.py]
<= macro.promise
promise = check_sdr_busy
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }} config-sdr = {{ sdr }}
[cell-gain-saturated-promise] [check-baseband-latency.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_baseband_latency
slapos.core
python-dateutil
file = {{ cell_gain_saturated_promise }}
output = ${directory:plugins}/check-cell-gain-saturated.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output} config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
config-min-txrx-delay = {{ slapparameter_dict.get("min_txrx_delay", 5) }}
[rx-saturated-promise] [check-amarisoft-stats-log.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_amarisoft_stats_log
slapos.core output = ${directory:plugins}/check-amarisoft-stats-log.py
python-dateutil
file = {{ rx_saturated_promise }}
output = ${directory:plugins}/check-rx-saturated.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output} config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
config-max-rx-sample-db = {{ slapparameter_dict.get("max_rx_sample_db", 0) }}
[baseband-latency-promise] [check-lopcomm-vswr.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_lopcomm_vswr
slapos.core
python-dateutil
file = {{ baseband_latency_promise }}
output = ${directory:plugins}/check-baseband-latency.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output} config-netconf-log = ${lopcomm-rrh-stats-template:json-log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
config-min-txrx-delay = {{ slapparameter_dict.get("min_txrx_delay", 5) }}
config-avg-txrx-delay = {{ slapparameter_dict.get("avg_txrx_delay", 7) }}
[vswr-promise] [check-rx-saturated.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_rx_saturated
slapos.core
python-dateutil
file = {{ vswr_promise }}
output = ${directory:plugins}/check-vswr.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-lopcomm-stats-log = ${lopcomm-rrh-stats-template:json-log-output}
[amarisoft-stats-log-promise]
recipe = slapos.cookbook:promise.plugin
eggs =
slapos.core
python-dateutil
file = {{ amarisoft_stats_log_promise }}
output = ${directory:plugins}/check-amarisoft-stats-log.py
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output} config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
config-max-rx-sample-db = {{ slapparameter_dict.get("max_rx_sample_db", 0) }}
[cpu-temperature-promise]
recipe = slapos.cookbook:promise.plugin
eggs =
slapos.core
python-dateutil
file = {{ cpu_temperature_promise }}
output = ${directory:plugins}/check-cpu-temperature.py
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-max-temp = {{ slapparameter_dict.get("promise_cpu_temperature_threshold", 90) }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold", 80) }}
config-max-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold_duration", 600) }}
...@@ -13,9 +13,7 @@ info = Your SIM card has been attached to service ${slap-configuration:instance- ...@@ -13,9 +13,7 @@ info = Your SIM card has been attached to service ${slap-configuration:instance-
parts = parts =
directory directory
lte-mme-request lte-mme-request
{% if not slapparameter_dict.get("sub-instance", False) %} check-cpu-temperature.py
cpu-temperature-promise
{% endif %}
publish-connection-information publish-connection-information
{% for part in part_list -%} {% for part in part_list -%}
{{ ' %s' % part }} {{ ' %s' % part }}
...@@ -76,17 +74,19 @@ config-slave-list = {{ dumps(slave_instance_list) }} ...@@ -76,17 +74,19 @@ config-slave-list = {{ dumps(slave_instance_list) }}
[monitor-base-url-dict] [monitor-base-url-dict]
lte-mme-request = ${lte-mme-request:connection-monitor-base-url} lte-mme-request = ${lte-mme-request:connection-monitor-base-url}
[cpu-temperature-promise] [macro.promise]
recipe = slapos.cookbook:promise.plugin <= monitor-promise-base
eggs = name = ${:_buildout_section_name_}
slapos.core
python-dateutil [check-cpu-temperature.py]
file = {{ cpu_temperature_promise }} <= macro.promise
output = ${directory:plugins}/check-cpu-temperature.py promise = check_cpu_temperature
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-max-temp = {{ slapparameter_dict.get("promise_cpu_temperature_threshold", 90) }} config-frequency = {{ slapparameter_dict.get("promise_cpu_temperature_frequency", 5) }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold", 80) }} config-max-spot-temp = {{ slapparameter_dict.get("promise_cpu_max_spot_temp", 90) }}
config-max-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold_duration", 600) }} config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_max_avg_temp", 80) }}
config-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temp_duration", 600) }}
config-avg-flag-file = ${directory:var}/promise_cpu_avg_flag_file
[publish-connection-information] [publish-connection-information]
recipe = slapos.cookbook:publish.serialised recipe = slapos.cookbook:publish.serialised
......
...@@ -14,7 +14,7 @@ parts = ...@@ -14,7 +14,7 @@ parts =
directory directory
lte-gnb-request lte-gnb-request
lte-mme-request lte-mme-request
cpu-temperature-promise check-cpu-temperature.py
publish-connection-information publish-connection-information
{% for part in part_list -%} {% for part in part_list -%}
{{ ' %s' % part }} {{ ' %s' % part }}
...@@ -87,17 +87,19 @@ return = monitor-base-url ...@@ -87,17 +87,19 @@ return = monitor-base-url
lte-mme-request = ${lte-mme-request:connection-monitor-base-url} lte-mme-request = ${lte-mme-request:connection-monitor-base-url}
lte-gnb-request = ${lte-gnb-request:connection-monitor-base-url} lte-gnb-request = ${lte-gnb-request:connection-monitor-base-url}
[cpu-temperature-promise] [macro.promise]
recipe = slapos.cookbook:promise.plugin <= monitor-promise-base
eggs = name = ${:_buildout_section_name_}
slapos.core
python-dateutil [check-cpu-temperature.py]
file = {{ cpu_temperature_promise }} <= macro.promise
output = ${directory:plugins}/check-cpu-temperature.py promise = check_cpu_temperature
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-max-temp = {{ slapparameter_dict.get("promise_cpu_temperature_threshold", 90) }} config-frequency = {{ slapparameter_dict.get("promise_cpu_temperature_frequency", 5) }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold", 80) }} config-max-spot-temp = {{ slapparameter_dict.get("promise_cpu_max_spot_temp", 90) }}
config-max-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold_duration", 600) }} config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_max_avg_temp", 80) }}
config-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temp_duration", 600) }}
config-avg-flag-file = ${directory:var}/promise_cpu_avg_flag_file
[publish-connection-information] [publish-connection-information]
recipe = slapos.cookbook:publish.serialised recipe = slapos.cookbook:publish.serialised
......
...@@ -172,9 +172,9 @@ ...@@ -172,9 +172,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -5,13 +5,16 @@ parts = ...@@ -5,13 +5,16 @@ parts =
lte-gnb-config lte-gnb-config
lte-enb-service lte-enb-service
amarisoft-stats-service amarisoft-stats-service
sdr-busy-promise {% if slapparameter_dict.get('rrh', '') == "Lopcomm ORAN" %}
cell-gain-saturated-promise lopcomm-rrh-stats-service
rx-saturated-promise check-lopcomm-vswr.py
amarisoft-stats-log-promise {% endif %}
{% if not slapparameter_dict.get("sub-instance", False) %} {% if not slapparameter_dict.get("sub-instance", False) %}
cpu-temperature-promise check-cpu-temperature.py
{% endif %} {% endif %}
check-sdr-busy.py
check-baseband-latency.py
check-amarisoft-stats-log.py
monitor-base monitor-base
publish-connection-information publish-connection-information
...@@ -93,6 +96,7 @@ inline = ...@@ -93,6 +96,7 @@ inline =
tail -c 1M ${:gnb-log} > ${:gnb-log}.tmp; tail -c 1M ${:gnb-log} > ${:gnb-log}.tmp;
mv ${:gnb-log}.tmp ${:gnb-log}; mv ${:gnb-log}.tmp ${:gnb-log};
{{ enb }}/lteenb ${directory:etc}/gnb.cfg >> ${:gnb-log} 2>> ${:gnb-log}; {{ enb }}/lteenb ${directory:etc}/gnb.cfg >> ${:gnb-log} 2>> ${:gnb-log};
{% endif %} {% endif %}
### eNodeB (enb) ### eNodeB (enb)
...@@ -119,14 +123,13 @@ context = ...@@ -119,14 +123,13 @@ context =
section directory directory section directory directory
key slapparameter_dict slap-configuration:configuration key slapparameter_dict slap-configuration:configuration
key log_file :log-output key log_file :log-output
raw stats_period {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} raw stats_period {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
raw testing {{ slapparameter_dict.get("testing", False) }} raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs raw python_path {{ buildout_directory}}/bin/pythonwitheggs
mode = 0775 mode = 0775
url = {{ amarisoft_stats_template }} url = {{ amarisoft_stats_template }}
output = ${directory:bin}/amarisoft-stats.py output = ${directory:bin}/amarisoft-stats.py
### eNodeB (enb)
[amarisoft-stats-service] [amarisoft-stats-service]
recipe = slapos.cookbook:wrapper recipe = slapos.cookbook:wrapper
command-line = ${amarisoft-stats-template:output} command-line = ${amarisoft-stats-template:output}
...@@ -167,68 +170,53 @@ monitor-title = {{ slapparameter_dict['name'] | string }} ...@@ -167,68 +170,53 @@ monitor-title = {{ slapparameter_dict['name'] | string }}
password = {{ slapparameter_dict['monitor-password'] | string }} password = {{ slapparameter_dict['monitor-password'] | string }}
{% endif %} {% endif %}
[sdr-busy-promise] [macro.promise]
recipe = slapos.cookbook:promise.plugin <= monitor-promise-base
eggs = slapos.core name = ${:_buildout_section_name_}
file = {{ sdr_busy_promise }}
output = ${directory:plugins}/check-sdr-busy.py
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }}
[cell-gain-saturated-promise] [check-cpu-temperature.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_cpu_temperature
slapos.core
python-dateutil
file = {{ cell_gain_saturated_promise }}
output = ${directory:plugins}/check-cell-gain-saturated.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output} config-frequency = {{ slapparameter_dict.get("promise_cpu_temperature_frequency", 5) }}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} config-max-spot-temp = {{ slapparameter_dict.get("promise_cpu_max_spot_temp", 90) }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_max_avg_temp", 80) }}
[rx-saturated-promise] config-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temp_duration", 600) }}
recipe = slapos.cookbook:promise.plugin config-avg-flag-file = ${directory:var}/promise_cpu_avg_flag_file
eggs =
slapos.core [check-sdr-busy.py]
python-dateutil <= macro.promise
file = {{ rx_saturated_promise }} promise = check_sdr_busy
output = ${directory:plugins}/check-rx-saturated.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output} config-sdr = {{ sdr }}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
config-max-rx-sample-db = {{ slapparameter_dict.get("max_rx_sample_db", 0) }}
[baseband-latency-promise] [check-baseband-latency.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_baseband_latency
slapos.core
python-dateutil
file = {{ baseband_latency_promise }}
output = ${directory:plugins}/check-baseband-latency.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output} config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} config-stats-period = {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
config-min-txrx-delay = {{ slapparameter_dict.get("min_txrx_delay", 5) }} config-min-txrx-delay = {{ slapparameter_dict.get("min_txrx_delay", 5) }}
config-avg-txrx-delay = {{ slapparameter_dict.get("avg_txrx_delay", 7) }}
[check-amarisoft-stats-log.py]
[amarisoft-stats-log-promise] <= macro.promise
recipe = slapos.cookbook:promise.plugin promise = check_amarisoft_stats_log
eggs =
slapos.core
python-dateutil
file = {{ amarisoft_stats_log_promise }}
output = ${directory:plugins}/check-amarisoft-stats-log.py output = ${directory:plugins}/check-amarisoft-stats-log.py
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output} config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} config-stats-period = {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
[cpu-temperature-promise] [check-lopcomm-vswr.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_lopcomm_vswr
slapos.core
python-dateutil
file = {{ cpu_temperature_promise }}
output = ${directory:plugins}/check-cpu-temperature.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-max-temp = {{ slapparameter_dict.get("promise_cpu_temperature_threshold", 90) }} config-netconf-log = ${lopcomm-rrh-stats-template:json-log-output}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold", 80) }} config-stats-period = {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
config-max-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold_duration", 600) }}
[check-rx-saturated.py]
<= macro.promise
promise = check_rx_saturated
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-amarisoft-stats-log = ${amarisoft-stats-template:log-output}
config-stats-period = {{ slapparameter_dict.get("gnb_stats_fetch_period", 60) }}
config-max-rx-sample-db = {{ slapparameter_dict.get("max_rx_sample_db", 0) }}
...@@ -4,9 +4,9 @@ parts = ...@@ -4,9 +4,9 @@ parts =
ltelogs ltelogs
lte-mme-config lte-mme-config
lte-mme-service lte-mme-service
tun-up-promise
monitor-base monitor-base
publish-connection-information publish-connection-information
check-interface-up.py
{% if slapparameter_dict.get("iperf3", None) %} {% if slapparameter_dict.get("iperf3", None) %}
iperf-service iperf-service
port-listening-promise port-listening-promise
...@@ -181,15 +181,16 @@ recipe = slapos.cookbook:publish.serialised ...@@ -181,15 +181,16 @@ recipe = slapos.cookbook:publish.serialised
epc-ipv6 = ${slap-configuration:ipv6-random} epc-ipv6 = ${slap-configuration:ipv6-random}
epc-ipv4 = {{ epc_ipv4 }} epc-ipv4 = {{ epc_ipv4 }}
# Add custom promise to check if /dev/sdr0 is busy [macro.promise]
[tun-up-promise] <= monitor-promise-base
recipe = slapos.cookbook:promise.plugin name = ${:_buildout_section_name_}
eggs = slapos.core
file = {{ interface_up_promise }} [check-interface-up.py]
output = ${directory:plugins}/check-tun-up.py <= macro.promise
promise = check_interface_up
config-testing = {{ slapparameter_dict.get("testing", False) }}
{% if not slapparameter_dict.get("testing", False) %} {% if not slapparameter_dict.get("testing", False) %}
config-ifname = ${slap-configuration:tun-name} config-ifname = ${slap-configuration:tun-name}
{% else %} {% else %}
config-ifname = config-ifname =
{% endif %} {% endif %}
config-testing = {{ slapparameter_dict.get("testing", False) }}
...@@ -152,20 +152,20 @@ ...@@ -152,20 +152,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -134,20 +134,20 @@ ...@@ -134,20 +134,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -170,9 +170,9 @@ ...@@ -170,9 +170,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -152,9 +152,9 @@ ...@@ -152,9 +152,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -152,20 +152,20 @@ ...@@ -152,20 +152,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -134,20 +134,20 @@ ...@@ -134,20 +134,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -170,9 +170,9 @@ ...@@ -170,9 +170,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -152,9 +152,9 @@ ...@@ -152,9 +152,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -152,20 +152,20 @@ ...@@ -152,20 +152,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -134,20 +134,20 @@ ...@@ -134,20 +134,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -170,9 +170,9 @@ ...@@ -170,9 +170,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -152,9 +152,9 @@ ...@@ -152,9 +152,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -152,20 +152,20 @@ ...@@ -152,20 +152,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -134,20 +134,20 @@ ...@@ -134,20 +134,20 @@
"type": "number", "type": "number",
"default": 7 "default": 7
}, },
"promise_cpu_temperature_threshold": { "promise_cpu_max_spot_temp": {
"title": "CPU temperature promise threshold", "title": "Maximum CPU spot temperature",
"description": "Temperature threshold above which CPU temperature promise will fail", "description": "Maximum CPU spot temperature above which CPU temperature promise will fail",
"type": "number", "type": "number",
"default": 90 "default": 90
}, },
"promise_cpu_avg_temperature_threshold": { "promise_cpu_max_avg_temp": {
"title": "Average CPU temperature promise threshold", "title": "Maximum average CPU temperature",
"description": "If average temperature over specified duration reaches this threshold, promise will fail", "description": "If average temperature over specified period reaches this threshold, promise will fail",
"type": "number", "type": "number",
"default": 80 "default": 80
}, },
"promise_cpu_avg_temperature_threshold_duration": { "promise_cpu_avg_temp_period": {
"title": "Average CPU temperature promise threshold duration", "title": "Period of Average CPU temperature checks",
"description": "Duration during which average temperature should not exceed specified threshold", "description": "Duration during which average temperature should not exceed specified threshold",
"type": "number", "type": "number",
"default": 600 "default": 600
......
...@@ -170,9 +170,9 @@ ...@@ -170,9 +170,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -152,9 +152,9 @@ ...@@ -152,9 +152,9 @@
"description": "Set to true to use IPv4 for AMF / MME addresses", "description": "Set to true to use IPv4 for AMF / MME addresses",
"type": "boolean" "type": "boolean"
}, },
"enb_stats_fetch_period": { "gnb_stats_fetch_period": {
"title": "eNB statistics fetch period (seconds)", "title": "gNB statistics fetch period (seconds)",
"description": "Describes how often a call to Amarisoft remote API is made to get eNB statistics", "description": "Describes how often a call to Amarisoft remote API is made to get gNB statistics",
"type": "number", "type": "number",
"default": 60 "default": 60
}, },
......
...@@ -4,8 +4,8 @@ parts = ...@@ -4,8 +4,8 @@ parts =
ltelogs ltelogs
lte-ue-lte-config lte-ue-lte-config
lte-ue-service lte-ue-service
sdr-busy-promise check-sdr-busy.py
cpu-temperature-promise check-cpu-temperature.py
monitor-base monitor-base
publish-connection-information publish-connection-information
...@@ -125,23 +125,22 @@ monitor-title = {{ slapparameter_dict['name'] | string }} ...@@ -125,23 +125,22 @@ monitor-title = {{ slapparameter_dict['name'] | string }}
password = {{ slapparameter_dict['monitor-password'] | string }} password = {{ slapparameter_dict['monitor-password'] | string }}
{% endif %} {% endif %}
# Add custom promise to check if /dev/sdr0 is busy [macro.promise]
[sdr-busy-promise] <= monitor-promise-base
recipe = slapos.cookbook:promise.plugin name = ${:_buildout_section_name_}
eggs = slapos.core
file = {{ sdr_busy_promise }} [check-cpu-temperature.py]
output = ${directory:plugins}/check-sdr-busy.py <= macro.promise
promise = check_cpu_temperature
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }} config-frequency = {{ slapparameter_dict.get("promise_cpu_temperature_frequency", 5) }}
config-max-spot-temp = {{ slapparameter_dict.get("promise_cpu_max_spot_temp", 90) }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_max_avg_temp", 80) }}
config-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temp_duration", 600) }}
config-avg-flag-file = ${directory:var}/promise_cpu_avg_flag_file
[cpu-temperature-promise] [check-sdr-busy.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_sdr_busy
slapos.core
python-dateutil
file = {{ cpu_temperature_promise }}
output = ${directory:plugins}/check-cpu-temperature.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-max-temp = {{ slapparameter_dict.get("promise_cpu_temperature_threshold", 90) }} config-sdr = {{ sdr }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold", 80) }}
config-max-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold_duration", 600) }}
...@@ -4,8 +4,8 @@ parts = ...@@ -4,8 +4,8 @@ parts =
ltelogs ltelogs
lte-ue-nr-config lte-ue-nr-config
lte-ue-service lte-ue-service
sdr-busy-promise check-sdr-busy.py
cpu-temperature-promise check-cpu-temperature.py
monitor-base monitor-base
publish-connection-information publish-connection-information
...@@ -128,23 +128,22 @@ monitor-title = {{ slapparameter_dict['name'] | string }} ...@@ -128,23 +128,22 @@ monitor-title = {{ slapparameter_dict['name'] | string }}
password = {{ slapparameter_dict['monitor-password'] | string }} password = {{ slapparameter_dict['monitor-password'] | string }}
{% endif %} {% endif %}
# Add custom promise to check if /dev/sdr0 is busy [macro.promise]
[sdr-busy-promise] <= monitor-promise-base
recipe = slapos.cookbook:promise.plugin name = ${:_buildout_section_name_}
eggs = slapos.core
file = {{ sdr_busy_promise }}
output = ${directory:plugins}/check-sdr-busy.py
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }}
[cpu-temperature-promise] [check-cpu-temperature.py]
recipe = slapos.cookbook:promise.plugin <= macro.promise
eggs = promise = check_cpu_temperature
slapos.core
python-dateutil
file = {{ cpu_temperature_promise }}
output = ${directory:plugins}/check-cpu-temperature.py
config-testing = {{ slapparameter_dict.get("testing", False) }} config-testing = {{ slapparameter_dict.get("testing", False) }}
config-max-temp = {{ slapparameter_dict.get("promise_cpu_temperature_threshold", 90) }} config-frequency = {{ slapparameter_dict.get("promise_cpu_temperature_frequency", 5) }}
config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold", 80) }} config-max-spot-temp = {{ slapparameter_dict.get("promise_cpu_max_spot_temp", 90) }}
config-max-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temperature_threshold_duration", 600) }} config-max-avg-temp = {{ slapparameter_dict.get("promise_cpu_max_avg_temp", 80) }}
config-avg-temp-duration = {{ slapparameter_dict.get("promise_cpu_avg_temp_duration", 600) }}
config-avg-flag-file = ${directory:var}/promise_cpu_avg_flag_file
[check-sdr-busy.py]
<= macro.promise
promise = check_sdr_busy
config-testing = {{ slapparameter_dict.get("testing", False) }}
config-sdr = {{ sdr }}
...@@ -32,7 +32,10 @@ context = ...@@ -32,7 +32,10 @@ context =
recipe = slapos.recipe.build recipe = slapos.recipe.build
init = init =
import os, re import os, re
try:
lte_version = sorted(filter(lambda x: re.match(r"v[0-9]{4}-[0-9]{2}-[0-9]{2}", x), os.listdir('/opt/amarisoft')))[-1][1:] lte_version = sorted(filter(lambda x: re.match(r"v[0-9]{4}-[0-9]{2}-[0-9]{2}", x), os.listdir('/opt/amarisoft')))[-1][1:]
except FileNotFoundError:
lte_version = 'LTEVERSION'
path = "/opt/amarisoft/v" + lte_version path = "/opt/amarisoft/v" + lte_version
options['lte-version'] = lte_version options['lte-version'] = lte_version
options['path'] = path options['path'] = path
...@@ -75,7 +78,6 @@ extensions = jinja2.ext.do ...@@ -75,7 +78,6 @@ extensions = jinja2.ext.do
extra-context = extra-context =
raw monitor_template ${monitor2-template:output} raw monitor_template ${monitor2-template:output}
key slave_instance_list slap-configuration:slave-instance-list key slave_instance_list slap-configuration:slave-instance-list
raw cpu_temperature_promise ${cpu-temperature-promise:target}
[dynamic-template-lte-gnb-epc] [dynamic-template-lte-gnb-epc]
< = jinja2-template-base < = jinja2-template-base
...@@ -85,7 +87,6 @@ extensions = jinja2.ext.do ...@@ -85,7 +87,6 @@ extensions = jinja2.ext.do
extra-context = extra-context =
raw monitor_template ${monitor2-template:output} raw monitor_template ${monitor2-template:output}
key slave_instance_list slap-configuration:slave-instance-list key slave_instance_list slap-configuration:slave-instance-list
raw cpu_temperature_promise ${cpu-temperature-promise:target}
[dynamic-template-lte-epc] [dynamic-template-lte-epc]
< = jinja2-template-base < = jinja2-template-base
...@@ -95,7 +96,6 @@ extensions = jinja2.ext.do ...@@ -95,7 +96,6 @@ extensions = jinja2.ext.do
extra-context = extra-context =
raw monitor_template ${monitor2-template:output} raw monitor_template ${monitor2-template:output}
key slave_instance_list slap-configuration:slave-instance-list key slave_instance_list slap-configuration:slave-instance-list
raw cpu_temperature_promise ${cpu-temperature-promise:target}
[dynamic-template-lte-enb] [dynamic-template-lte-enb]
< = jinja2-template-base < = jinja2-template-base
...@@ -111,13 +111,6 @@ extra-context = ...@@ -111,13 +111,6 @@ extra-context =
raw ltelogs_template ${ltelogs.jinja2.sh:target} raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw amarisoft_stats_template ${amarisoft-stats.jinja2.py:target} raw amarisoft_stats_template ${amarisoft-stats.jinja2.py:target}
raw lopcomm_rrh_stats_template ${lopcomm-rrh-stats.jinja2.py:target} raw lopcomm_rrh_stats_template ${lopcomm-rrh-stats.jinja2.py:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
raw cell_gain_saturated_promise ${cell-gain-saturated-promise:target}
raw rx_saturated_promise ${rx-saturated-promise:target}
raw baseband_latency_promise ${baseband-latency-promise:target}
raw amarisoft_stats_log_promise ${amarisoft-stats-log-promise:target}
raw cpu_temperature_promise ${cpu-temperature-promise:target}
raw vswr_promise ${vswr-promise:target}
raw openssl_location ${openssl:location} raw openssl_location ${openssl:location}
raw default_dl_earfcn ${default-params:default-dl-earfcn} raw default_dl_earfcn ${default-params:default-dl-earfcn}
raw default_lte_dl_freq ${default-params:default-lte-dl-freq} raw default_lte_dl_freq ${default-params:default-lte-dl-freq}
...@@ -143,12 +136,6 @@ extra-context = ...@@ -143,12 +136,6 @@ extra-context =
raw gnb_template ${gnb.jinja2.cfg:target} raw gnb_template ${gnb.jinja2.cfg:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target} raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw amarisoft_stats_template ${amarisoft-stats.jinja2.py:target} raw amarisoft_stats_template ${amarisoft-stats.jinja2.py:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
raw cell_gain_saturated_promise ${cell-gain-saturated-promise:target}
raw rx_saturated_promise ${rx-saturated-promise:target}
raw baseband_latency_promise ${baseband-latency-promise:target}
raw amarisoft_stats_log_promise ${amarisoft-stats-log-promise:target}
raw cpu_temperature_promise ${cpu-temperature-promise:target}
raw openssl_location ${openssl:location} raw openssl_location ${openssl:location}
raw default_dl_nr_arfcn ${default-params:default-dl-nr-arfcn} raw default_dl_nr_arfcn ${default-params:default-dl-nr-arfcn}
raw default_nr_band ${default-params:default-nr-band} raw default_nr_band ${default-params:default-nr-band}
...@@ -171,7 +158,6 @@ filename = instance-lte-mme.cfg ...@@ -171,7 +158,6 @@ filename = instance-lte-mme.cfg
extensions = jinja2.ext.do extensions = jinja2.ext.do
extra-context = extra-context =
raw monitor_template ${monitor2-template:output} raw monitor_template ${monitor2-template:output}
raw interface_up_promise ${interface-up-promise:target}
key mme amarisoft:mme key mme amarisoft:mme
raw mme_template ${mme.jinja2.cfg:target} raw mme_template ${mme.jinja2.cfg:target}
raw ims_template ${ims.jinja2.cfg:target} raw ims_template ${ims.jinja2.cfg:target}
...@@ -188,13 +174,10 @@ filename = instance-lte-ue-lte.cfg ...@@ -188,13 +174,10 @@ filename = instance-lte-ue-lte.cfg
extensions = jinja2.ext.do extensions = jinja2.ext.do
extra-context = extra-context =
raw monitor_template ${monitor2-template:output} raw monitor_template ${monitor2-template:output}
raw interface_up_promise ${interface-up-promise:target}
key ue amarisoft:ue key ue amarisoft:ue
key sdr amarisoft:sdr key sdr amarisoft:sdr
raw ue_lte_template ${ue-lte.jinja2.cfg:target} raw ue_lte_template ${ue-lte.jinja2.cfg:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target} raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
raw cpu_temperature_promise ${cpu-temperature-promise:target}
raw openssl_location ${openssl:location} raw openssl_location ${openssl:location}
raw default_dl_earfcn ${default-params:default-dl-earfcn} raw default_dl_earfcn ${default-params:default-dl-earfcn}
raw default_lte_dl_freq ${default-params:default-lte-dl-freq} raw default_lte_dl_freq ${default-params:default-lte-dl-freq}
...@@ -213,13 +196,10 @@ filename = instance-lte-ue-nr.cfg ...@@ -213,13 +196,10 @@ filename = instance-lte-ue-nr.cfg
extensions = jinja2.ext.do extensions = jinja2.ext.do
extra-context = extra-context =
raw monitor_template ${monitor2-template:output} raw monitor_template ${monitor2-template:output}
raw interface_up_promise ${interface-up-promise:target}
key ue amarisoft:ue key ue amarisoft:ue
key sdr amarisoft:sdr key sdr amarisoft:sdr
raw ue_nr_template ${ue-nr.jinja2.cfg:target} raw ue_nr_template ${ue-nr.jinja2.cfg:target}
raw cpu_temperature_promise ${cpu-temperature-promise:target}
raw ltelogs_template ${ltelogs.jinja2.sh:target} raw ltelogs_template ${ltelogs.jinja2.sh:target}
raw sdr_busy_promise ${sdr-busy-promise:target}
raw openssl_location ${openssl:location} raw openssl_location ${openssl:location}
raw default_dl_nr_arfcn ${default-params:default-dl-nr-arfcn} raw default_dl_nr_arfcn ${default-params:default-dl-nr-arfcn}
raw default_nr_band ${default-params:default-nr-band} raw default_nr_band ${default-params:default-nr-band}
......
import errno
import json
import os
from datetime import datetime
from dateutil import parser
from zope.interface import implementer
from slapos.grid.promise import interface
from slapos.grid.promise.generic import GenericPromise
# Get latest timestamp from JSON log
def get_latest_timestamp(log):
log_number = 0
while True:
try:
f = open("{}.{}".format(log, log_number) if log_number else log, "rb")
except OSError:
return 0
try:
f.seek(0, os.SEEK_END)
try:
while f.seek(-2, os.SEEK_CUR) and f.read(1) != b'\n':
pass
except OSError:
break
l = json.loads(f.readline().decode().replace("'", '"'))
return parser.parse(l['time'])
finally:
f.close()
log_number += 1
return 0
@implementer(interface.IPromise)
class RunPromise(GenericPromise):
def __init__(self, config):
super(RunPromise, self).__init__(config)
self.setPeriodicity(minute=1)
def sense(self):
amarisoft_stats_log = self.getConfig('amarisoft-stats-log')
stats_period = int(self.getConfig('stats-period'))
latest_timestamp = get_latest_timestamp(amarisoft_stats_log)
delta = (datetime.now() - latest_timestamp).total_seconds()
if delta > stats_period * 2:
self.logger.error("Latest entry from amarisoft statistics log too "\
"old (%s seconds old)" % (delta,))
else:
self.logger.info("Latest entry from amarisoft statistics is "\
"%s seconds old" % (delta,))
def test(self):
"""
Called after sense() if the instance is still converging.
Returns success or failure based on sense results.
In this case, fail if the previous sensor result is negative.
"""
return self._test(result_count=1, failure_amount=1)
def anomaly(self):
"""
Called after sense() if the instance has finished converging.
Returns success or failure based on sense results.
Failure signals the instance has diverged.
In this case, fail if two out of the last three results are negative.
"""
return self._anomaly(result_count=1, failure_amount=1)
import errno
import json
import logging
import os
from dateutil import parser
from zope.interface import implementer
from slapos.grid.promise import interface
from slapos.grid.promise.generic import GenericPromise
# Get all data in the last "interval" seconds from JSON log
def get_data_interval(log, interval):
log_number = 0
latest_timestamp = 0
data_list = []
while True:
try:
f = open("{}.{}".format(log, log_number) if log_number else log, "rb")
except OSError:
return data_list
try:
f.seek(0, os.SEEK_END)
while True:
try:
while f.seek(-2, os.SEEK_CUR) and f.read(1) != b'\n':
pass
except OSError:
break
pos = f.tell()
l = json.loads(f.readline().decode().replace("'", '"'))
timestamp = parser.parse(l['time'])
data_list.append(l['data'])
if not latest_timestamp:
latest_timestamp = timestamp
if (latest_timestamp - timestamp).total_seconds() > interval:
return data_list
f.seek(pos, os.SEEK_SET)
finally:
f.close()
log_number += 1
@implementer(interface.IPromise)
class RunPromise(GenericPromise):
def __init__(self, config):
self.__name = config.get('name', None)
self.__log_folder = config.get('log-folder', None)
super(RunPromise, self).__init__(config)
self.setPeriodicity(minute=1)
self.__title = os.path.splitext(self.__name)[0]
self.__log_file = os.path.join(self.__log_folder, '%s.json.log' % self.__title)
self.json_logger = logging.getLogger('json_logger')
self.json_logger.setLevel(logging.INFO)
handler = logging.FileHandler(self.__log_file)
formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
handler.setFormatter(formatter)
self.json_logger.addHandler(handler)
def sense(self):
testing = self.getConfig('testing') == "True"
if testing:
self.logger.info("skipping promise")
return
amarisoft_stats_log = self.getConfig('amarisoft-stats-log')
stats_period = int(self.getConfig('stats-period'))
min_txrx_delay = float(self.getConfig('min-txrx-delay', 5))
avg_txrx_delay = float(self.getConfig('avg-txrx-delay', 7))
data_list = get_data_interval(amarisoft_stats_log, stats_period * 2)
min_txrx_delay_list = []
avg_txrx_delay_list = []
min_unavailable = False
avg_unavailable = False
for data in data_list:
rf_list = data['rf']
if not min_txrx_delay_list:
min_txrx_delay_list = [99 for x in rf_list]
if not avg_txrx_delay_list:
avg_txrx_delay_list = [99 for x in rf_list]
for i, rxtx_delay_avg in enumerate(rf_list):
min_txrx_delay_list[i] = min(min_txrx_delay_list[i], float(rf_list['rxtx_delay_min']))
min_delay = min_txrx_delay_list[i]
if min_txrx_delay_list[i] >= min_txrx_delay:
min_unavailable = True
for i, rxtx_delay_avg in enumerate(rf_list):
avg_txrx_delay_list[i] = min(avg_txrx_delay_list[i], float(rf_list['rxtx_delay_avg']))
avg_delay = avg_txrx_delay_list[i]
if avg_txrx_delay_list[i] >= avg_txrx_delay:
avg_unavailable = True
self.json_logger.info("The minimum available time for radio front end processing (ms)",
extra={'data': min_txrx_delay_list})
if not min_txrx_delay_list or not avg_txrx_delay:
self.logger.error("No TX/RX diff data available")
elif min_unavailable:
self.logger.error("The minimum available time %s (ms) for radio front end processing is higher than a threshold %s (ms) depending on the radio front end." % (min_delay, min_txrx_delay))
elif avg_unavailable:
self.logger.error("The average available time %s (ms) for radio front end processing is higher than a threshold %s (ms) depending on the radio front end." % (avg_delay, avg_txrx_delay))
else:
self.logger.info("The minimum %s (ms) and average %s (ms) available time for radio front end processing OK" % (min_delay, avg_delay))
def test(self):
"""
Called after sense() if the instance is still converging.
Returns success or failure based on sense results.
In this case, fail if the previous sensor result is negative.
"""
return self._test(result_count=1, failure_amount=1)
def anomaly(self):
"""
Called after sense() if the instance has finished converging.
Returns success or failure based on sense results.
Failure signals the instance has diverged.
In this case, fail if two out of the last three results are negative.
"""
return self._anomaly(result_count=1, failure_amount=1)
import errno
import json
import logging
import os
from dateutil import parser
from zope.interface import implementer
from slapos.grid.promise import interface
from slapos.grid.promise.generic import GenericPromise
# Get latest data and data from "interval" seconds ago from JSON log
def get_data_interval(log, interval):
log_number = 0
latest_timestamp = 0
latest_data = {}
while True:
try:
f = open("{}.{}".format(log, log_number) if log_number else log, "rb")
except OSError:
return latest_data, {}
try:
f.seek(0, os.SEEK_END)
while True:
try:
while f.seek(-2, os.SEEK_CUR) and f.read(1) != b'\n':
pass
except OSError:
break
pos = f.tell()
l = json.loads(f.readline().decode().replace("'", '"'))
timestamp = parser.parse(l['time'])
if not latest_timestamp:
latest_timestamp = timestamp
latest_data = l['data']
if (latest_timestamp - timestamp).total_seconds() > interval:
return latest_data, l['data']
f.seek(pos, os.SEEK_SET)
finally:
f.close()
log_number += 1
@implementer(interface.IPromise)
class RunPromise(GenericPromise):
def __init__(self, config):
self.__name = config.get('name', None)
self.__log_folder = config.get('log-folder', None)
super(RunPromise, self).__init__(config)
self.setPeriodicity(minute=1)
self.__title = os.path.splitext(self.__name)[0]
self.__log_file = os.path.join(self.__log_folder, '%s.json.log' % self.__title)
self.json_logger = logging.getLogger('json_logger')
self.json_logger.setLevel(logging.INFO)
handler = logging.FileHandler(self.__log_file)
formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
handler.setFormatter(formatter)
self.json_logger.addHandler(handler)
def sense(self):
testing = self.getConfig('testing') == "True"
amarisoft_stats_log = self.getConfig('amarisoft-stats-log')
stats_period = int(self.getConfig('stats-period'))
latest_data, previous_data = get_data_interval(amarisoft_stats_log, stats_period * 2)
def get_saturation_events(data):
if data:
return sum([x['sat'] for x in data['samples']['rx']])
return 0
saturation_events = get_saturation_events(latest_data) - \
get_saturation_events(previous_data)
self.json_logger.info("Saturation events",
extra={'data': {'recent_saturation_events': saturation_events}})
if saturation_events:
self.logger.error("Reception saturated, please lower cell_gain")
else:
self.logger.info("No saturation events on reception")
def test(self):
"""
Called after sense() if the instance is still converging.
Returns success or failure based on sense results.
In this case, fail if the previous sensor result is negative.
"""
return self._test(result_count=1, failure_amount=1)
def anomaly(self):
"""
Called after sense() if the instance has finished converging.
Returns success or failure based on sense results.
Failure signals the instance has diverged.
In this case, fail if two out of the last three results are negative.
"""
return self._anomaly(result_count=1, failure_amount=1)
import socket
import errno
import logging
import json
import os
import psutil
from dateutil import parser
from zope.interface import implementer
from slapos.grid.promise import interface
from slapos.grid.promise.generic import GenericPromise
# Get all data in the last "interval" seconds from JSON log
def get_data_interval(log, interval):
log_number = 0
latest_timestamp = 0
data_list = []
while True:
try:
f = open("{}.{}".format(log, log_number) if log_number else log, "rb")
except OSError:
return data_list
try:
f.seek(0, os.SEEK_END)
while True:
try:
while f.seek(-2, os.SEEK_CUR) and f.read(1) != b'\n':
pass
except OSError:
break
pos = f.tell()
l = json.loads(f.readline().decode().replace("'", '"'))
timestamp = parser.parse(l['time'])
data_list.append(l['data'])
if not latest_timestamp:
latest_timestamp = timestamp
if (latest_timestamp - timestamp).total_seconds() > interval:
return data_list
f.seek(pos, os.SEEK_SET)
finally:
f.close()
log_number += 1
@implementer(interface.IPromise)
class RunPromise(GenericPromise):
def __init__(self, config):
self.__name = config.get('name', None)
self.__log_folder = config.get('log-folder', None)
super(RunPromise, self).__init__(config)
self.setPeriodicity(minute=2)
self.__title = os.path.splitext(self.__name)[0]
self.__log_file = os.path.join(self.__log_folder, '%s.json.log' % self.__title)
self.json_logger = logging.getLogger('json_logger')
self.json_logger.setLevel(logging.INFO)
handler = logging.FileHandler(self.__log_file)
formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
handler.setFormatter(formatter)
self.json_logger.addHandler(handler)
def sense(self):
max_temp = float(self.getConfig('max-temp', 90))
max_avg_temp = float(self.getConfig('max-avg-temp', 80))
max_avg_temp_duration = int(self.getConfig('max-avg-temp-duration', 300))
testing = self.getConfig('testing') == "True"
if testing:
from random import randint
cpu_temp = randint(40, 75)
else:
data = psutil.sensors_temperatures()
cpu_temp = data['coretemp'][0][1]
l = get_data_interval(self.__log_file, max_avg_temp_duration) or [{'cpu_temperature': cpu_temp}]
avg_temp = sum(map(lambda x: x['cpu_temperature'], l)) / len(l)
data = json.dumps({'cpu_temperature': cpu_temp, 'avg_cpu_temperature': avg_temp})
self.json_logger.info("Temperature data", extra={'data': data})
promise_success = True
if cpu_temp > max_temp:
self.logger.error("Temperature reached critical threshold: %s degrees celsius (threshold is %s degrees celsius)" % (cpu_temp, max_temp))
promise_success = False
if avg_temp > max_avg_temp:
self.logger.error("Average temperature over the last %s seconds reached threshold: %s degrees celsius (threshold is %s degrees celsius)" % (max_avg_temp_duration, avg_temp, max_avg_temp))
promise_success = False
if promise_success:
self.logger.info("Temperature OK")
def test(self):
"""
Called after sense() if the instance is still converging.
Returns success or failure based on sense results.
In this case, fail if the previous sensor result is negative.
"""
return self._test(result_count=1, failure_amount=1)
def anomaly(self):
"""
Called after sense() if the instance has finished converging.
Returns success or failure based on sense results.
Failure signals the instance has diverged.
In this case, fail if two out of the last three results are negative.
"""
return self._anomaly(result_count=3, failure_amount=2)
import socket
import errno
from zope.interface import implementer
from slapos.grid.promise import interface
from slapos.grid.promise.generic import GenericPromise
@implementer(interface.IPromise)
class RunPromise(GenericPromise):
def __init__(self, config):
super(RunPromise, self).__init__(config)
self.setPeriodicity(minute=2)
def sense(self):
ifname = self.getConfig('ifname')
testing = self.getConfig('testing') == "True"
if testing:
self.logger.info("skipping promise")
return
f = open('/sys/class/net/%s/operstate' % ifname, 'r')
if f.read() == 'up\n':
self.logger.info("%s is up", ifname)
else:
self.logger.error("%s is down", ifname)
f.close()
def test(self):
"""
Called after sense() if the instance is still converging.
Returns success or failure based on sense results.
In this case, fail if the previous sensor result is negative.
"""
return self._test(result_count=1, failure_amount=1)
def anomaly(self):
"""
Called after sense() if the instance has finished converging.
Returns success or failure based on sense results.
Failure signals the instance has diverged.
In this case, fail if two out of the last three results are negative.
"""
return self._anomaly(result_count=3, failure_amount=2)
import errno
import json
import logging
import os
from dateutil import parser
from zope.interface import implementer
from slapos.grid.promise import interface
from slapos.grid.promise.generic import GenericPromise
# Get all data in the last "interval" seconds from JSON log
def get_data_interval(log, interval):
log_number = 0
latest_timestamp = 0
data_list = []
while True:
try:
f = open("{}.{}".format(log, log_number) if log_number else log, "rb")
except OSError:
return data_list
try:
f.seek(0, os.SEEK_END)
while True:
try:
while f.seek(-2, os.SEEK_CUR) and f.read(1) != b'\n':
pass
except OSError:
break
pos = f.tell()
l = json.loads(f.readline().decode().replace("'", '"'))
timestamp = parser.parse(l['time'])
data_list.append(l['data'])
if not latest_timestamp:
latest_timestamp = timestamp
if (latest_timestamp - timestamp).total_seconds() > interval:
return data_list
f.seek(pos, os.SEEK_SET)
finally:
f.close()
log_number += 1
@implementer(interface.IPromise)
class RunPromise(GenericPromise):
def __init__(self, config):
self.__name = config.get('name', None)
self.__log_folder = config.get('log-folder', None)
super(RunPromise, self).__init__(config)
self.setPeriodicity(minute=1)
self.__title = os.path.splitext(self.__name)[0]
self.__log_file = os.path.join(self.__log_folder, '%s.json.log' % self.__title)
self.json_logger = logging.getLogger('json_logger')
self.json_logger.setLevel(logging.INFO)
handler = logging.FileHandler(self.__log_file)
formatter = logging.Formatter('{"time": "%(asctime)s", "log_level": "%(levelname)s", "message": "%(message)s", "data": %(data)s}')
handler.setFormatter(formatter)
self.json_logger.addHandler(handler)
def sense(self):
testing = self.getConfig('testing') == "True"
amarisoft_stats_log = self.getConfig('amarisoft-stats-log')
stats_period = int(self.getConfig('stats-period'))
max_rx_sample_db = float(self.getConfig('max-rx-sample-db'))
data_list = get_data_interval(amarisoft_stats_log, stats_period * 2)
max_rx = []
saturated = False
for data in data_list:
rx_list = data['samples']['rx']
if not max_rx:
max_rx = [-99.9 for x in rx_list]
for i, rx in enumerate(rx_list):
max_rx[i] = max(max_rx[i], float(rx['max']))
if max_rx[i] >= max_rx_sample_db:
saturated = True
self.json_logger.info("RX maximum sample values (dB)",
extra={'data': max_rx})
if not max_rx:
self.logger.error("No RX samples data available")
elif saturated:
self.logger.error("RX antenna saturated, please lower rx_gain")
else:
self.logger.info("No saturation detected on RX antenna")
def test(self):
"""
Called after sense() if the instance is still converging.
Returns success or failure based on sense results.
In this case, fail if the previous sensor result is negative.
"""
return self._test(result_count=1, failure_amount=1)
def anomaly(self):
"""
Called after sense() if the instance has finished converging.
Returns success or failure based on sense results.
Failure signals the instance has diverged.
In this case, fail if two out of the last three results are negative.
"""
return self._anomaly(result_count=1, failure_amount=1)
import os
import errno
import subprocess
from zope.interface import implementer
from slapos.grid.promise import interface
from slapos.grid.promise.generic import GenericPromise
@implementer(interface.IPromise)
class RunPromise(GenericPromise):
def __init__(self, config):
super(RunPromise, self).__init__(config)
self.setPeriodicity(minute=1)
def sense(self):
testing = self.getConfig('testing') == "True"
sdr = self.getConfig('sdr')
if testing:
self.logger.info("skipping promise")
return
try:
out = subprocess.check_output([
sdr + '/sdr_util', '-c', '0', 'version'], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
if e.returncode == 1 and \
("DMA channel is already opened" in e.output.decode() or \
"Device or resource busy" in e.output.decode()):
self.logger.info("eNB is using /dev/sdr0")
return
self.logger.error("eNB is not using /dev/sdr0")
def test(self):
"""
Called after sense() if the instance is still converging.
Returns success or failure based on sense results.
In this case, fail if the previous sensor result is negative.
"""
return self._test(result_count=1, failure_amount=1)
def anomaly(self):
"""
Called after sense() if the instance has finished converging.
Returns success or failure based on sense results.
Failure signals the instance has diverged.
In this case, fail if two out of the last three results are negative.
"""
return self._anomaly(result_count=1, failure_amount=1)
...@@ -9,6 +9,7 @@ extends = ...@@ -9,6 +9,7 @@ extends =
../../component/python3/buildout.cfg ../../component/python3/buildout.cfg
parts += parts +=
# slapos.toolbox-dev
template template
slapos-cookbook slapos-cookbook
ltelogs.jinja2.sh ltelogs.jinja2.sh
...@@ -27,6 +28,18 @@ parts += ...@@ -27,6 +28,18 @@ parts +=
# apache-php # apache-php
# logrotate # logrotate
# [slapos.toolbox-repository]
# recipe = slapos.recipe.build:gitclone
# repository = https://lab.nexedi.com/nexedi/slapos.toolbox.git
# branch = ors
# git-executable = ${git:location}/bin/git
# develop = true
# [slapos.toolbox-dev]
# recipe = zc.recipe.egg:develop
# egg = slapos.toolbox
# setup = ${slapos.toolbox-repository:location}
# depends = ${slapos-toolbox-dependencies:eggs}
[template] [template]
recipe = slapos.recipe.template recipe = slapos.recipe.template
...@@ -67,23 +80,6 @@ url = ${:_profile_base_location_}/${:_update_hash_filename_} ...@@ -67,23 +80,6 @@ url = ${:_profile_base_location_}/${:_update_hash_filename_}
[template-lte-ue-nr] [template-lte-ue-nr]
<= download-base <= download-base
[sdr-busy-promise]
<= download-base
[cell-gain-saturated-promise]
<= download-base
[rx-saturated-promise]
<= download-base
[baseband-latency-promise]
<= download-base
[amarisoft-stats-log-promise]
<= download-base
[cpu-temperature-promise]
<= download-base
[interface-up-promise]
<= download-base
[vswr-promise]
<= download-base
[copy-to-instance] [copy-to-instance]
recipe = slapos.recipe.build:download recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_buildout_section_name_} url = ${:_profile_base_location_}/${:_buildout_section_name_}
...@@ -146,3 +142,4 @@ interpreter = pythonwitheggs ...@@ -146,3 +142,4 @@ interpreter = pythonwitheggs
websocket-client = 1.4.2 websocket-client = 1.4.2
ncclient = 0.6.13 ncclient = 0.6.13
xmltodict = 0.13.0 xmltodict = 0.13.0
# slapos.toolbox =
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment