instance-enb.jinja2.cfg 12.1 KB
Newer Older
1
# instance-enb implements eNB/gNB service.
2 3 4 5 6 7
{#- defaults for global eNB/gNB parameters.
    TODO automatically load enb defaults from JSON schema #}
{%- set enb_defaults = {
  'com_ws_port':  9001,
  'com_addr':     '127.0.1.2',
  'use_ipv4':     False,
8 9
  'gnb_id_bits':  28,
  'nssai':        {'1': {'sst': 1}},
10
  'xlog_forwarding_enabled': True,
11 12
  'wendelin_telecom_software_release_url': 'wendelin-telecom-enb-shared-instance',
  'xlog_fluentbit_forward_port': 24224,
13 14 15 16 17
} %}
{%- set gtp_addr_lo = '127.0.1.1' %}
{%- for k,v in enb_defaults|dictsort %}
{%-   do slapparameter_dict.setdefault(k, v) %}
{%- endfor %}
18
{%- set B = xbuildout.encode %}
19

20

21
[buildout]
22
extra-parts =
23 24
parts =
  directory
25 26
  enb-config
  enb-service
27
  xamari-xlog-service
28
  request-wendelin-telecom-shared
29 30
{%- if slapparameter_dict.xlog_forwarding_enabled %}
  xlog-fluentbit-service
31 32
  check-xlog-fluentbit-forward-host.py
  check-xlog-fluentbit-health.py
33
{%- endif %}
34 35
  nginx-launcher
  nginx-graceful
36
  check-baseband-latency.py
37
  monitor-base
38
  publish-connection-information
39
  ${:extra-parts}
40 41 42 43 44 45 46

extends = {{ monitor_template }}

eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true

47
{%- set icell_kind='enb'                                        %}
48
{%- import 'slaplte.jinja2'            as slaplte with context  %}
49
{%- import 'ru_libinstance.jinja2.cfg' as rulib   with context  %}
50 51 52 53 54
{%- set ipeer_dict = {}                                         %}
{%- set ipeercell_dict = {}                                     %}
{%- do slaplte.load_ipeer(ipeer_dict)                           %}
{%- do slaplte.load_ipeercell(ipeercell_dict)                   %}
{%- do slaplte.check_loaded_everything()                        %}
55

56 57
{{ rulib.buildout() }}

58 59 60 61 62 63
[myslap]
# NOTE we don't query slapos.cookbook:slapconfiguration the second time because
# slapparameter_dict is potentially modified with defaults.
parameter_dict = {{ dumps(slapparameter_dict) }}
configuration = {{ dumps(slap_configuration) }}

64

65 66 67 68 69 70 71 72 73 74 75 76 77 78
[monitor-httpd-conf-parameter]
httpd-include-file = {{ buildout_directory }}/etc/httpd-include-file.conf
port = ${monitor-instance-parameter:monitor-httpd-port}
url = https://[${monitor-instance-parameter:monitor-httpd-ipv6}]:${:port}

[monitor-instance-parameter]
monitor-httpd-port = ${monitor-address:port}

[monitor-address]
recipe = slapos.cookbook:free_port
minimum = 8035
maximum = 8055
ip = ${monitor-instance-parameter:monitor-httpd-ipv6}

79 80 81 82 83 84 85 86

[directory]
recipe = slapos.cookbook:mkdirectory
software = {{ buildout_directory }}
home = ${buildout:directory}
var = ${:home}/var
etc = ${:home}/etc
bin = ${:home}/bin
87
tmp = ${:home}/tmp
88 89 90 91 92
run = ${:var}/run
script = ${:etc}/run
service = ${:etc}/service
promise = ${:etc}/promise
log = ${:var}/log
93
xlog-fluentbit = ${:var}/xlog-fluentbit
94

95
[enb-sh-wrapper]
96 97
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
98 99
enb-info-log = ${directory:log}/enb-info.log
enb-info-archive-log = ${directory:log}/enb-info.log
100 101
enb-radio-log = ${directory:log}/enb.log
enb-start-date = ${directory:run}/enb-start.date
102 103
inline =
  #!/bin/sh
104
  # Amarisoft init scripts
105 106 107
  sudo -n {{ amarisoft['dir'] }}/rm-tmp-lte
  sudo -n {{ amarisoft['dir'] }}/init-sdr {{ amarisoft['dir'] }}/v{{ amarisoft['version'] }};
  sudo -n {{ amarisoft['dir'] }}/init-enb
108 109
  # Add useful information to enb-info log
  (echo && echo && date "+[%Y/%m/%d %T.%N %Z] Starting eNB software...") >> ${:enb-info-log}
110
  (echo -n "PCB: " ; for o in t b v s ; do sudo -n {{ sdr['dir'] }}/get-sdr-info -$o 2> /dev/null ; echo -n " " ; done ; echo) >> ${:enb-info-log}
111
  echo "System info: $(uname -a)" >> ${:enb-info-log}
112
  ({{ amarisoft['sdr_dir'] }}/sdr_util version && echo) >> ${:enb-info-log}
113 114 115 116
  # Remove obsolete logs
  rm -f ${directory:log}/enb-2024*
  rm -f ${directory:log}/gnb*
  rm -f ${directory:log}/enb-output.log
117
  # Keep the 50 latest enb radio log
118
  stat ${:enb-start-date} && mv ${:enb-radio-log} ${directory:log}/enb.log.$(cat ${:enb-start-date})
119
  rm -f $(ls -1t ${directory:log}/enb-2* | tail -n+50)
120
  rm -f $(ls -1t ${directory:log}/enb-info-2* | tail -n+50)
121
  date +"%Y%m%d.%T" > ${:enb-start-date}
122 123 124 125 126 127 128
  # Trim enb info log to 500k and keep a 100M archive of enb info log
  head -c -500k ${:enb-info-log} >> ${:enb-info-archive-log}
  tail -c 500k ${:enb-info-log} > ${:enb-info-log}.tmp
  mv ${:enb-info-log}.tmp ${:enb-info-log}
  tail -c 100M ${:enb-info-archive-log} > ${:enb-info-archive-log}.tmp
  mv ${:enb-info-archive-log}.tmp ${:enb-info-archive-log}
  # Launch lteenb
129
  {{ amarisoft['enb_dir'] }}/lteenb ${directory:etc}/enb.cfg >> ${:enb-info-log} 2>> ${:enb-info-log}
130

131
[enb-service]
132
recipe = slapos.cookbook:wrapper
133 134
command-line = ${enb-sh-wrapper:output}
wrapper-path = ${directory:service}/enb
135 136 137 138
mode = 0775
reserve-cpu = True
pidfile = ${directory:run}/enb.pid
hash-files =
139 140
  ${enb-config:output}
  ${enb-sh-wrapper:output}
141 142
environment =
  LD_LIBRARY_PATH={{ openssl_location }}/lib
143
  AMARISOFT_PATH={{ amarisoft['license_dir'] }}
144

145 146 147 148 149 150 151 152 153 154
[xamari-xlog-script]
recipe = slapos.recipe.template
output = ${directory:bin}/${:_buildout_section_name_}
period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
stats_logspec = stats[samples,rf]/${:period}s
{%- if slapparameter_dict.get("enb_drb_stats_enabled", True) %}
drb_stats_logspec = x.drb_stats/${:period}s
{%- else %}
drb_stats_logspec =
{%- endif %}
155
rotatespec = 100MB.9
156 157 158 159 160
logspec = ${:stats_logspec} ${:drb_stats_logspec}
xamari = {{ buildout_directory }}/bin/xamari
logfile = ${monitor-directory:public}/enb.xlog
inline =
  #!/bin/sh
161
  exec ${:xamari} xlog --rotate ${:rotatespec} --password ${websocket-password:passwd} ws://{{ slapparameter_dict.com_addr }}:{{ slapparameter_dict.com_ws_port }} ${:logfile} ${:logspec}
162 163 164 165 166 167 168

[xamari-xlog-service]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:service}/${:_buildout_section_name_}
command-line = ${xamari-xlog-script:output}
hash-files = ${:command-line}

169 170 171 172 173 174 175 176 177 178 179 180 181
[request-parameters]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Wendelin Telecom Registration
software-url = {{ slapparameter_dict.wendelin_telecom_software_release_url }}
shared = true
{%- if not slapparameter_dict.xlog_forwarding_enabled or slapparameter_dict.get("xlog_fluentbit_forward_host") %}
state = destroyed
{%- else %}
config-fluentbit-tag = ${xlog-fluentbit-tag:xlog-fluentbit-tag}
return = gateway-host
{%- endif %}

182 183 184 185 186 187 188 189 190 191 192 193 194 195
[request-wendelin-telecom-shared]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Wendelin Telecom Registration
software-url = {{ slapparameter_dict.wendelin_telecom_software_release_url }}
shared = true
{%- if not slapparameter_dict.xlog_forwarding_enabled or slapparameter_dict.get("xlog_fluentbit_forward_host") %}
state = destroyed
{%- else %}
config-fluentbit-tag = ${xlog-fluentbit-tag:xlog-fluentbit-tag}
return = gateway-host
{%- endif %}

{% if slapparameter_dict.xlog_forwarding_enabled %}
196 197 198
[xlog-fluentbit-tag]
recipe = slapos.recipe.build
computer = ${slap-connection:computer-id}
199 200
enb-id = {{ slapparameter_dict.get("enb_id", "") }}
gnb-id = {{ slapparameter_dict.get("gnb_id", "") }}
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
init =
  import socket

  options['hostname'] = socket.gethostname()

  radio_id = ''
  if options['enb-id']:
    radio_id = 'e%s' % options['enb-id'] 
  elif options['gnb-id']:
    radio_id = 'g%s' % options['gnb-id']
  options['radio-id'] = radio_id

  xlog_fluentbit_tag = '_'.join(options[x] for x in ('hostname', 'computer', 'radio-id') if options[x])
  options['xlog-fluentbit-tag'] = xlog_fluentbit_tag

216 217 218 219
[xlog-fluentbit-config]
recipe = slapos.recipe.template
output = ${directory:etc}/${:_buildout_section_name_}.cfg
logfile = ${xamari-xlog-script:logfile}
220
forward-host = {{ slapparameter_dict.get('xlog_fluentbit_forward_host', '') or '${request-wendelin-telecom-shared:connection-gateway-host}' }}
221
forward-port = {{ slapparameter_dict.xlog_fluentbit_forward_port }}
222
forward-shared-key = {{ slapparameter_dict.get('xlog_fluentbit_forward_shared_key', '') }}
223
forward-self-hostname = {{ B(comp_id['comp-id']) }}
224 225
monitoring-host = {{ my_ipv4 }}
monitoring-port = {{ slapparameter_dict.xlog_fluentbit_forward_port + 1 }}
226 227 228
inline =
  [SERVICE]
      flush           5
229 230 231 232 233 234 235
      HTTP_Server     On
      HTTP_Listen     ${:monitoring-host}
      HTTP_PORT       ${:monitoring-port}
      Health_Check    On
      HC_Errors_Count 0
      HC_Retry_Failure_Count 0
      HC_Period       60
236 237 238
  [INPUT]
      name            tail
      path            ${:logfile}
239
      tag             ${xlog-fluentbit-tag:xlog-fluentbit-tag}
240
      Read_from_Head  True
241
      db              ${directory:xlog-fluentbit}/tail-state
242
      Buffer_Max_Size 1M
243 244 245 246 247
  [OUTPUT]
      name            forward
      match           *
      Host            ${:forward-host}
      Port            ${:forward-port}
248
{%- if slapparameter_dict.get('xlog_fluentbit_forward_shared_key') %}
249
      Shared_Key      ${:forward-shared-key}
250
{%- endif %}
251
      Self_Hostname   ${:forward-self-hostname}
252
      Retry_Limit     50
253 254 255 256 257 258 259 260 261 262
      tls             on
      tls.verify      off

[xlog-fluentbit-service]
recipe  = slapos.cookbook:wrapper
fluentbit =  {{ fluent_bit_location }}/bin/fluent-bit
fluentbit-config = ${xlog-fluentbit-config:output}
command-line = ${:fluentbit} -c ${:fluentbit-config}
wrapper-path = ${directory:service}/${:_buildout_section_name_}
hash-files = ${:fluentbit-config}
263 264 265 266 267 268 269 270 271 272 273

[check-xlog-fluentbit-forward-host.py]
<= macro.promise
promise = check_socket_listening
config-host = ${xlog-fluentbit-config:forward-host}
config-port = ${xlog-fluentbit-config:forward-port}

[check-xlog-fluentbit-health.py]
<= macro.promise
promise = check_url_available
config-url = http://${xlog-fluentbit-config:monitoring-host}:${xlog-fluentbit-config:monitoring-port}/api/v1/health
274
{%- endif %}
275

276 277 278
[config-base]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
279
extra-context =
280
context =
281
  json ors false
282
  section directory directory
283 284 285
  key slap_configuration myslap:configuration
  key slapparameter_dict myslap:parameter_dict
  raw gtp_addr_v6 {{ my_ipv6 }}
286
  raw gtp_addr_v4 {{ lan_ipv4 }}
287
  raw gtp_addr_lo {{ gtp_addr_lo }}
288
  import  xbuildout xbuildout
289
  import  netaddr netaddr
290
  ${:extra-context}
291

292
[enb-config]
293
<= config-base
294 295
url = {{ enb_template }}
output = ${directory:etc}/enb.cfg
296 297
import-list =
    rawfile slaplte.jinja2 {{ slaplte_template }}
298 299 300 301 302 303
extra-context =
    import json_module json
    key iru_dict       :iru_dict
    key icell_dict     :icell_dict
    key ipeer_dict     :ipeer_dict
    key ipeercell_dict :ipeercell_dict
304
    key websocket_password websocket-password:passwd
305 306 307 308
iru_dict       = {{ dumps(rulib.iru_dict) }}
icell_dict     = {{ dumps(rulib.icell_dict) }}
ipeer_dict     = {{ dumps(ipeer_dict) }}
ipeercell_dict = {{ dumps(ipeercell_dict) }}
309

310 311

[publish-connection-information]
312
<= monitor-publish
313
recipe = slapos.cookbook:publish.serialised
314 315 316
websocket-address = ${request-slave-frontend:connection-domain}/${nginx-params:websocket-path}
websocket-port = 443
websocket-password = ${websocket-password:passwd}
317
enb-ipv6 = {{ my_ipv6 }}
318
enb-ipv4 = {{ lan_ipv4 }}
319 320 321 322
amarisoft-version = {{ amarisoft['version'] }}
amarisoft-host-id = {{ amarisoft['lteenb_host_id'] }}
amarisoft-available-versions = {{ amarisoft['version_installed'] }}
license-expiration = {{ amarisoft['lteenb_expiration'] }}
323
monitor-gadget-url = ${:monitor-base-url}/gadget/software.cfg.html
324 325 326 327
ru-list   = {{ dumps(rulib.iru_dict.keys()   | sort) }}
cell-list = {{ dumps(rulib.icell_dict.keys() | sort) }}
peer-list = {{ dumps(ipeer_dict.keys()       | sort) }}
peer-cell-list = {{ dumps(ipeercell_dict.keys() | sort) }}
328
{%- if slapparameter_dict.xlog_forwarding_enabled %}
329
fluentbit-tag = ${xlog-fluentbit-tag:xlog-fluentbit-tag}
330
{%- endif %}
331

332 333

[monitor-instance-parameter]
334
{% if slapparameter_dict.get("name", None) %}
335
monitor-title = {{ slapparameter_dict['name'] | string }}
336 337
{% endif %}
{% if slapparameter_dict.get("monitor-password", None) %}
338
password = {{ slapparameter_dict['monitor-password'] | string }}
339
{% endif %}
340

341 342 343 344 345 346 347
[macro.promise]
<= monitor-promise-base
name = ${:_buildout_section_name_}

[check-baseband-latency.py]
<= macro.promise
promise = check_baseband_latency
348
config-amarisoft-stats-log = ${ru_amarisoft-stats-template:log-output}
349
config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }}
350
config-min-rxtx-delay = {{ slapparameter_dict.get("min_rxtx_delay", 0) }}
351