[buildout] parts = switch-softwaretype eggs-directory = ${buildout:eggs-directory} develop-eggs-directory = ${buildout:develop-eggs-directory} offline = true [directory] recipe = slapos.cookbook:mkdirectory software = ${buildout:directory} home = $${buildout:directory} etc = $${:home}/etc [slap-configuration] recipe = slapos.cookbook:slapconfiguration.serialised computer = $${slap-connection:computer-id} partition = $${slap-connection:partition-id} url = $${slap-connection:server-url} key = $${slap-connection:key-file} cert = $${slap-connection:cert-file} [jinja2-template-base] recipe = slapos.recipe.template:jinja2 output = $${buildout:directory}/$${:filename} extra-context = depends = $${activate-eggs:recipe} context = import xbuildout xbuildout import json_module json import netaddr netaddr import nrarfcn_module nrarfcn import xearfcn_module xlte.earfcn import xnrarfcn_module xlte.nrarfcn key eggs_directory buildout:eggs-directory key develop_eggs_directory buildout:develop-eggs-directory raw buildout_directory ${buildout:directory} section directory directory raw pythonwitheggs ${buildout:bin-directory}/pythonwitheggs section slap_connection slap-connection key slapparameter_dict slap-configuration:configuration key lan_ipv4 lan:ipv4 key mac lan:mac key my_ipv4 slap-configuration:ipv4-random key my_ipv6 slap-configuration:ipv6-random raw nginx_template ${nginx_conf.in:target} raw nginx_mime ${nginx-output:mime} raw nginx_executable ${nginx-output:nginx} raw openssl_executable_location ${openssl:location}/bin/openssl $${:extra-context} import-list = rawfile slaplte.jinja2 ${slaplte.jinja2:target} rawfile ru_libinstance.jinja2.cfg ${ru_libinstance.jinja2.cfg:target} rawfile ru_sdr_libinstance.jinja2.cfg ${ru_sdr_libinstance.jinja2.cfg:target} rawfile ru_sunwave_libinstance.jinja2.cfg ${ru_sunwave_libinstance.jinja2.cfg:target} # activate eggs and modules used in jinja2 templates [activate-eggs] recipe = slapos.recipe.build init = import pkg_resources as rpkg buildout = self.buildout['buildout'] env = rpkg.Environment([buildout['develop-eggs-directory'], buildout['eggs-directory']]) env.scan() def activate(pkgspec): req = rpkg.Requirement.parse(pkgspec) for dist in rpkg.working_set.resolve([req], env): rpkg.working_set.add(dist) activate('xlte') activate('nrarfcn') # ~ import xbuildout import sys, types def readfile(path): with open(path) as f: return f.read() xbuildout = types.ModuleType('xbuildout') exec(readfile('${ru_xbuildout.py:target}'), xbuildout.__dict__) assert 'xbuildout' not in sys.modules sys.modules['xbuildout'] = xbuildout [sdr] recipe = slapos.recipe.build configuration = $${slap-configuration:configuration} init = # Set SDR directory options['dir'] = options['configuration'].get('sdr_dir', '/opt/sdr') [amarisoft] recipe = slapos.recipe.build fixed_version = 2024-11-21.1732633257 configuration = $${slap-configuration:configuration} init = import os, re mock = options['configuration'].get('lte_mock', False) # Set Amarisoft directory options['dir'] = options['configuration'].get('amarisoft_dir', '/opt/amarisoft') # Get Available Amarisoft versions if mock: version_installed = [options['fixed_version']] else: version_installed = [x[1:] for x in os.listdir(options['dir']) if re.match(r"v[0-9]{4}-[0-9]{2}-[0-9]{2}.[0-9]{10}", x)] options['version_installed'] = ', '.join(version_installed) # Set Amarisoft version to use slapconf_version = options['configuration'].get('amarisoft_version', False) if slapconf_version and \ slapconf_version in version_installed: options['version'] = slapconf_version else: options['version'] = options['fixed_version'] # Set Binaries and license directories binary_dir = options['dir'] + "/v" + options['version'] options['license_dir'] = options['dir'] + '/.amarisoft' options['sdr_dir'] = binary_dir + '/trx_sdr' options['enb_dir'] = binary_dir + '/enb' options['mme_dir'] = binary_dir + '/mme' options['ims_dir'] = binary_dir + '/mme' options['ue_dir'] = binary_dir + '/ue' if options['configuration'].get('lte_mock', False): options['enb_dir'] = '${buildout:directory}/bin' options['mme_dir'] = '${buildout:directory}/bin' options['ims_dir'] = '${buildout:directory}/bin' options['ue_dir'] = '${buildout:directory}/bin' # Get License expiration and host IDs if mock: options.update({'lteenb_expiration': '9999-99-99', 'ltemme_expiration': '9999-99-99', 'lteue_expiration': '9999-99-99'}) options.update({'lteenb_host_id': '00-00-00-00-00-00-00-00', 'ltemme_host_id': '00-00-00-00-00-00-00-00', 'lteue_host_id': '00-00-00-00-00-00-00-00'}) else: options.update({'lteenb_expiration': 'Unknown', 'ltemme_expiration': 'Unknown', 'lteue_expiration': 'Unknown'}) options.update({'lteenb_host_id': 'Unknown', 'ltemme_host_id': 'Unknown', 'lteue_host_id': 'Unknown'}) try: for filename in os.listdir(options['license_dir']): if filename.endswith('.key'): with open(os.path.join(options['license_dir'], filename), 'r') as f: f.seek(260) for l in f: if l.startswith('host_id='): host_id = l.split('=')[1].strip() if l.startswith('product_id='): product_id = l.split('=')[1].strip() if l.startswith('version='): expiration = l.split('=')[1].strip() options[product_id + '_expiration'] = expiration options[product_id + '_host_id'] = host_id except FileNotFoundError: pass [lan] recipe = slapos.recipe.build init = import netifaces for i in netifaces.interfaces(): if not (i.startswith("slaptun") or i.startswith("slaptap") or i.startswith("re6stnet") or i == "lo"): a = netifaces.ifaddresses(i) if netifaces.AF_INET in a: try: options['ipv4'] = a[netifaces.AF_INET][0]['addr'] except: options['ipv4'] = "0.0.0.0" try: options['mac'] = a[netifaces.AF_LINK][0]['addr'] except: options['mac'] = "00:00:00:00:00:00" [ors-id] recipe = slapos.recipe.build configuration = $${slap-configuration:configuration} init = import socket try: sn = int(socket.gethostname().split('ors')[1]) except (IndexError, ValueError): sn = 0 options['serial_number'] = sn options['enb_id'] = "0x{:05X}".format(sn % 2**20) options['gnb_id'] = "0x{:05X}".format((sn + 2**19) % 2**20) options['enb_pci'] = sn % 504 options['gnb_pci'] = sn % 1008 options['enb_cell_id'] = "0x{:02X}".format(sn % 2**8) options['gnb_cell_id'] = "0x{:02X}".format((sn + 2**7) % 2**8) options['root_sequence_index'] = sn % 834 def to_int(x): try: if '0x' in enb_id: return int(x, 16) return int(x) except ValueError: return 0 enb_id = options['configuration'].get('enb_id', options['enb_id']) gnb_id = options['configuration'].get('enb_id', options['enb_id']) cell_id = options['configuration'].get('cell_id', options['enb_cell_id']) gnb_id_bits = options['configuration'].get('gnb_id_bits', 28) options['eutra_cell_id'] = \ "0x{:07X}".format(to_int(enb_id) * 2**8 + to_int(cell_id)) options['nr_cell_id'] = \ "0x{:07X}".format(to_int(gnb_id) * 2**(36 - gnb_id_bits) + to_int(cell_id)) [comp-id] recipe = slapos.recipe.build computer = $${slap-connection:computer-id} title = $${slap-configuration:root-instance-title} init = import socket options['hostname'] = socket.gethostname() comp_id = '_'.join(options[x] for x in ('hostname', 'computer', 'title')) options['comp-id'] = comp_id [switch-softwaretype] recipe = slapos.cookbook:switch-softwaretype # we don't select default software type to force user to choose the correct one enb = dynamic-template-enb:output core-network = dynamic-template-core-network:output ue = dynamic-template-ue:output [dynamic-template-enb] < = jinja2-template-base url = ${template-enb:target} filename = instance-enb.cfg extensions = jinja2.ext.do extra-context = raw monitor_template ${monitor2-template:output} section comp_id comp-id section slap_configuration slap-configuration section amarisoft amarisoft section ors_id ors-id section sdr sdr raw enb_template ${enb.jinja2.cfg:target} raw slaplte_template ${slaplte.jinja2:target} raw drb_lte_template ${drb_lte.jinja2.cfg:target} raw drb_nr_template ${drb_nr.jinja2.cfg:target} raw sib23_template ${sib23.jinja2.asn:target} raw ru_amarisoft_stats_template ${ru_amarisoft-stats.jinja2.py:target} raw ru_amarisoft_rf_info_template ${ru_amarisoft-rf-info.jinja2.py:target} raw ru_tapsplit ${ru_tapsplit:target} raw netcapdo ${netcapdo:exe} raw openssl_location ${openssl:location} raw ru_dnsmasq_template ${ru_dnsmasq.jinja2.cfg:target} raw dnsmasq_location ${dnsmasq:location} raw fluent_bit_location ${fluent-bit:location} raw openssh_location ${openssh:location} raw openssh_output_keygen ${openssh-output:keygen} [dynamic-template-core-network] < = jinja2-template-base url = ${template-core-network:target} filename = instance-core-network.cfg extensions = jinja2.ext.do extra-context = raw monitor_template ${monitor2-template:output} section amarisoft amarisoft section sdr sdr raw mme_template ${mme.jinja2.cfg:target} raw dnsmasq_template ${dnsmasq-core-network.jinja2.cfg:target} raw ims_template ${ims.jinja2.cfg:target} raw ue_db_template ${ue_db.jinja2.cfg:target} raw mt_call_template ${mt_call_qos.jinja2.sdp:target} raw netcapdo ${netcapdo:exe} raw openssl_location ${openssl:location} raw nghttp2_location ${nghttp2:location} raw iperf3_location ${iperf3:location} raw dnsmasq_location ${dnsmasq:location} key slave_instance_list slap-configuration:slave-instance-list section slap_configuration slap-configuration [dynamic-template-ue] < = jinja2-template-base url = ${template-ue:target} filename = instance-ue.cfg extensions = jinja2.ext.do extra-context = section slap_configuration slap-configuration section amarisoft amarisoft section sdr sdr raw monitor_template ${monitor2-template:output} raw ue_template ${ue.jinja2.cfg:target} raw slaplte_template ${slaplte.jinja2:target} raw openssl_location ${openssl:location} raw ru_amarisoft_stats_template ${ru_amarisoft-stats.jinja2.py:target} raw ru_amarisoft_rf_info_template ${ru_amarisoft-rf-info.jinja2.py:target} raw ru_tapsplit ${ru_tapsplit:target} raw netcapdo ${netcapdo:exe} raw ru_dnsmasq_template ${ru_dnsmasq.jinja2.cfg:target} raw dnsmasq_location ${dnsmasq:location} raw openssh_location ${openssh:location} raw openssh_output_keygen ${openssh-output:keygen}