# instance-enb implements eNB/gNB service. {#- 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, 'gnb_id_bits': 28, 'nssai': {'1': {'sst': 1}}, 'wendelin_telecom_software_release_url': 'wendelin-telecom-enb-shared-instance', 'xlog_fluentbit_forward_host': 'fluentd.rapid.space', 'xlog_fluentbit_forward_port': 24224, } %} {%- set gtp_addr_lo = '127.0.1.1' %} {%- for k,v in enb_defaults|dictsort %} {%- do slapparameter_dict.setdefault(k, v) %} {%- endfor %} {%- set B = xbuildout.encode %} [buildout] extra-parts = parts = directory enb-config enb-service xamari-xlog-service xlog-fluentbit-service request-wendelin-telecom-shared check-baseband-latency.py monitor-base publish-connection-information ${:extra-parts} extends = {{ monitor_template }} eggs-directory = {{ eggs_directory }} develop-eggs-directory = {{ develop_eggs_directory }} offline = true {%- set icell_kind='enb' %} {%- import 'slaplte.jinja2' as slaplte with context %} {%- import 'ru_libinstance.jinja2.cfg' as rulib with context %} {%- set ipeer_dict = {} %} {%- set ipeercell_dict = {} %} {%- do slaplte.load_ipeer(ipeer_dict) %} {%- do slaplte.load_ipeercell(ipeercell_dict) %} {%- do slaplte.check_loaded_everything() %} {{ rulib.buildout() }} [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) }} [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} [directory] recipe = slapos.cookbook:mkdirectory software = {{ buildout_directory }} home = ${buildout:directory} var = ${:home}/var etc = ${:home}/etc bin = ${:home}/bin tmp = ${:home}/tmp run = ${:var}/run script = ${:etc}/run service = ${:etc}/service promise = ${:etc}/promise log = ${:var}/log xlog-fluentbit = ${:var}/xlog-fluentbit [enb-sh-wrapper] recipe = slapos.recipe.template output = ${directory:bin}/${:_buildout_section_name_} enb-info-log = ${directory:log}/enb-info.log enb-info-archive-log = ${directory:log}/enb-info.log enb-radio-log = ${directory:log}/enb.log enb-start-date = ${directory:run}/enb-start.date inline = #!/bin/sh {% if not slapparameter_dict.get("testing", False) %} # Amarisoft init scripts sudo -n /opt/amarisoft/rm-tmp-lte sudo -n /opt/amarisoft/init-sdr sudo -n /opt/amarisoft/init-enb # Add useful information to enb-info log (echo && echo && date "+[%Y/%m/%d %T.%N %Z] Starting eNB software...") >> ${:enb-info-log} (echo -n "PCB: " ; for o in t b v s ; do sudo -n /opt/amarisoft/get-sdr-info -$o 2> /dev/null ; echo -n " " ; done ; echo) >> ${:enb-info-log} (AMARISOFT_PATH=/dev/null {{ enb }}/lteenb ${directory:etc}/enb.cfg 2>&1 >/dev/null | sed -n 's/^.*\(Host ID.*\)$/\1/gp') >> ${:enb-info-log} echo "System info: $(uname -a)" >> ${:enb-info-log} ({{ sdr }}/sdr_util version && echo) >> ${:enb-info-log} # Keep the 50 latest enb radio log stat ${:enb-start-date} && mv ${:enb-radio-log} ${directory:log}/enb-$(cat ${:enb-start-date}).log rm -f $(ls -1t ${directory:log}/enb-2* | tail -n+50) rm -f $(ls -1t ${directory:log}/enb-info-2* | tail -n+50) date +"%Y-%m-%d-%T" > ${:enb-start-date} # 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 {{ enb }}/lteenb ${directory:etc}/enb.cfg >> ${:enb-info-log} 2>> ${:enb-info-log} {% endif %} [enb-service] recipe = slapos.cookbook:wrapper command-line = ${enb-sh-wrapper:output} wrapper-path = ${directory:service}/enb mode = 0775 reserve-cpu = True pidfile = ${directory:run}/enb.pid hash-files = ${enb-config:output} ${enb-sh-wrapper:output} environment = LD_LIBRARY_PATH={{ openssl_location }}/lib AMARISOFT_PATH=/opt/amarisoft/.amarisoft [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 %} rotatespec = 100MB.9 logspec = ${:stats_logspec} ${:drb_stats_logspec} {%- if slapparameter_dict.get("websocket_password", "") %} websock = ws://[{{my_ipv6}}]:9001 {%- else %} websock = ws://127.0.1.2:9001 {%- endif %} xamari = {{ buildout_directory }}/bin/xamari logfile = ${monitor-directory:public}/enb.xlog inline = #!/bin/sh exec ${:xamari} xlog --rotate ${:rotatespec} ${:websock} ${:logfile} ${:logspec} [xamari-xlog-service] recipe = slapos.cookbook:wrapper wrapper-path = ${directory:service}/${:_buildout_section_name_} command-line = ${xamari-xlog-script:output} hash-files = ${:command-line} [xlog-fluentbit-tag] recipe = slapos.recipe.build computer = ${slap-connection:computer-id} enb-id = {{ slapparameter_dict.get("enb_id") }} gnb-id = {{ slapparameter_dict.get("gnb_id") }} 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 [xlog-fluentbit-config] recipe = slapos.recipe.template output = ${directory:etc}/${:_buildout_section_name_}.cfg logfile = ${xamari-xlog-script:logfile} forward-host = {{ slapparameter_dict.xlog_fluentbit_forward_host }} forward-port = {{ slapparameter_dict.xlog_fluentbit_forward_port }} forward-shared-key = {{ slapparameter_dict.get('xlog_fluentbit_forward_shared_key', '') }} forward-self-hostname = {{ B(comp_id['comp-id']) }} inline = [SERVICE] flush 5 [INPUT] name tail path ${:logfile} tag ${xlog-fluentbit-tag:xlog-fluentbit-tag} Read_from_Head True db ${directory:xlog-fluentbit}/tail-state [OUTPUT] name forward match * Host ${:forward-host} Port ${:forward-port} {%- if slapparameter_dict.get('xlog_fluentbit_forward_shared_key') %} Shared_Key ${:forward-shared-key} {%- endif %} Self_Hostname ${:forward-self-hostname} 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} [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 config-fluentbit-tag = ${xlog-fluentbit-tag:xlog-fluentbit-tag} [config-base] recipe = slapos.recipe.template:jinja2 extensions = jinja2.ext.do extra-context = context = json ors false section directory directory key slap_configuration myslap:configuration key slapparameter_dict myslap:parameter_dict raw gtp_addr_v6 {{ my_ipv6 }} raw gtp_addr_v4 {{ lan_ipv4 }} raw gtp_addr_lo {{ gtp_addr_lo }} import xbuildout xbuildout import netaddr netaddr ${:extra-context} [enb-config] <= config-base url = {{ enb_template }} output = ${directory:etc}/enb.cfg import-list = rawfile slaplte.jinja2 {{ slaplte_template }} 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 iru_dict = {{ dumps(rulib.iru_dict) }} icell_dict = {{ dumps(rulib.icell_dict) }} ipeer_dict = {{ dumps(ipeer_dict) }} ipeercell_dict = {{ dumps(ipeercell_dict) }} [publish-connection-information] <= monitor-publish recipe = slapos.cookbook:publish.serialised {%- if slapparameter_dict.get("websocket_password", "") %} websocket_url = ws://[{{my_ipv6}}]:9001 {%- endif %} enb-ipv6 = {{ my_ipv6 }} enb-ipv4 = {{ lan_ipv4 }} amarisoft-version = {{ lte_version }} license-expiration = {{ lte_expiration }} monitor-gadget-url = ${:monitor-base-url}/gadget/software.cfg.html 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) }} fluentbit-tag = ${xlog-fluentbit-tag:xlog-fluentbit-tag} [monitor-instance-parameter] {% if slapparameter_dict.get("name", None) %} monitor-title = {{ slapparameter_dict['name'] | string }} {% endif %} {% if slapparameter_dict.get("monitor-password", None) %} password = {{ slapparameter_dict['monitor-password'] | string }} {% endif %} [macro.promise] <= monitor-promise-base name = ${:_buildout_section_name_} [check-baseband-latency.py] <= macro.promise promise = check_baseband_latency config-testing = {{ slapparameter_dict.get("testing", False) }} config-amarisoft-stats-log = ${ru_amarisoft-stats-template:log-output} config-stats-period = {{ slapparameter_dict.get("enb_stats_fetch_period", 60) }} config-min-rxtx-delay = {{ slapparameter_dict.get("min_rxtx_delay", 0) }}