mirror of https://gerrit.osmocom.org/osmo-dev
net: get missing config variables from config_2g3g
Don't ask the user to copy config_2g3g and manually keep it in sync with config_2g3g with each change anymore. Instead, let the user config be a diff on top of config_2g3g. This is in preparation to adding new variables for use with OsmoBSCNAT. Change-Id: I5870d39aee8be84c2024f8a2a71ee4a734a4fc7c
This commit is contained in:
parent
02f2254b23
commit
b252b4a043
68
net/README
68
net/README
|
@ -10,28 +10,55 @@ contributions of any improvements you may have!
|
||||||
|
|
||||||
=== Quick Start
|
=== Quick Start
|
||||||
|
|
||||||
cp config_2g3g config_mine
|
* Open config_2g3g in a text editor (original config)
|
||||||
$EDITOR config_mine
|
* Open a new file in a text editor (your config)
|
||||||
# update IP addresses and device names as required
|
* Copy over all lines you want to change in your config and edit them there
|
||||||
|
* Your resulting minimal config could look like this:
|
||||||
|
|
||||||
mkdir my_network
|
TERMINAL="tmux"
|
||||||
cd my_network
|
|
||||||
../fill_config.py ../config_mine ../templates
|
|
||||||
|
|
||||||
./run.sh
|
ETH_DEV=enp0s25
|
||||||
# Launches numerous x-terminals with one component running in each.
|
|
||||||
# Logs and pcap traces are being taken automatically.
|
|
||||||
|
|
||||||
# hit enter in the original first terminal to tear down all programs.
|
TO_RAN_IP="192.168.1.123"
|
||||||
# Enter a name to save logs, otherwise all logging will be stored
|
TO_RAN_IU_IP="192.168.1.42"
|
||||||
# under autolog/<timestamp>
|
|
||||||
|
|
||||||
Then possibly modify the config and refresh:
|
MCC=999
|
||||||
|
MNC=99
|
||||||
|
|
||||||
# tweak config?
|
BTS0_IPA_UNIT="1234 0"
|
||||||
$EDITOR ../config_mine
|
BTS0_ARFCN=800
|
||||||
../fill_config.py
|
|
||||||
# picks up same ../config_mine and ../templates from last time
|
* Create a network directory and generate configs:
|
||||||
|
|
||||||
|
$ mkdir my_network
|
||||||
|
$ cd my_network
|
||||||
|
$ ../fill_config.py ../config_mine ../templates
|
||||||
|
|
||||||
|
* Run the network:
|
||||||
|
|
||||||
|
$ ./run.sh
|
||||||
|
|
||||||
|
This launches numerous terminals with one component running in each.
|
||||||
|
Logs and pcap traces are being taken automatically.
|
||||||
|
|
||||||
|
* Tear down:
|
||||||
|
|
||||||
|
Hit enter in the original first terminal to tear down all programs.
|
||||||
|
Enter a name to save logs, otherwise all logging will be stored
|
||||||
|
under autolog/<timestamp>.
|
||||||
|
|
||||||
|
* Regenerate configs:
|
||||||
|
|
||||||
|
Modify your config and regenerate the network configs as follows, the same
|
||||||
|
original config, your config and templates will be used as last time.
|
||||||
|
|
||||||
|
$ $EDITOR ../config_mine
|
||||||
|
$ ../fill_config.py
|
||||||
|
|
||||||
|
('make regen' also works)
|
||||||
|
|
||||||
|
|
||||||
|
=== Advanced usage / more examples
|
||||||
|
|
||||||
# own templates?
|
# own templates?
|
||||||
cp -r ../templates ../templates_mine
|
cp -r ../templates ../templates_mine
|
||||||
|
@ -67,7 +94,7 @@ A *directory* contains template files that are filled with specific values by th
|
||||||
fill_config.py script. See e.g. templates/.
|
fill_config.py script. See e.g. templates/.
|
||||||
|
|
||||||
A *file* contains local config items as name=val pairs that are put into the
|
A *file* contains local config items as name=val pairs that are put into the
|
||||||
templates. See e.g. config_2g3g.
|
templates. It is usually a subset of config_2g3g.
|
||||||
|
|
||||||
The fill_config.py script helps to fill the templates with the config values. Simply
|
The fill_config.py script helps to fill the templates with the config values. Simply
|
||||||
invoke fill_config.py with a dir argument (templates dir) and a file argument (specific
|
invoke fill_config.py with a dir argument (templates dir) and a file argument (specific
|
||||||
|
@ -77,6 +104,11 @@ temporary files (sockets etc.) should be placed inside this folder.
|
||||||
If one or both are omitted, the script tries to re-use the most recent paths,
|
If one or both are omitted, the script tries to re-use the most recent paths,
|
||||||
they were stored in local files '.last_config' and '.last_templates'.
|
they were stored in local files '.last_config' and '.last_templates'.
|
||||||
|
|
||||||
|
The -o parameter of fill_config.py can be used to supply a different original
|
||||||
|
config file than config_2g3g. If it is omitted, the path is read from a
|
||||||
|
'.last_config_orig' file inside the network directory if present, and config_2g3g
|
||||||
|
is used otherwise.
|
||||||
|
|
||||||
The result is a complete set of .cfg files that match your local machine and
|
The result is a complete set of .cfg files that match your local machine and
|
||||||
network config.
|
network config.
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,9 @@ import argparse
|
||||||
def file_newer(path_a, than_path_b):
|
def file_newer(path_a, than_path_b):
|
||||||
return os.path.getmtime(path_a) > os.path.getmtime(than_path_b)
|
return os.path.getmtime(path_a) > os.path.getmtime(than_path_b)
|
||||||
|
|
||||||
|
DEFAULT_ORIG_CONFIG = os.path.normpath(os.path.realpath(__file__) + "/../config_2g3g")
|
||||||
LAST_LOCAL_CONFIG_FILE = '.last_config'
|
LAST_LOCAL_CONFIG_FILE = '.last_config'
|
||||||
|
LAST_ORIG_CONFIG_FILE = '.last_config_orig'
|
||||||
LAST_TMPL_DIR = '.last_templates'
|
LAST_TMPL_DIR = '.last_templates'
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description=__doc__,
|
parser = argparse.ArgumentParser(description=__doc__,
|
||||||
|
@ -18,10 +20,14 @@ parser.add_argument('sources', metavar='SRC', nargs='*',
|
||||||
parser.add_argument('-s', '--check-stale', dest='check_stale', action='store_true',
|
parser.add_argument('-s', '--check-stale', dest='check_stale', action='store_true',
|
||||||
help='only verify age of generated files vs. config and templates.'
|
help='only verify age of generated files vs. config and templates.'
|
||||||
' Exit nonzero when any source file is newer. Do not write anything.')
|
' Exit nonzero when any source file is newer. Do not write anything.')
|
||||||
|
parser.add_argument('-o', '--original-config',
|
||||||
|
help='get missing variables from this file, default is config_2g3g'
|
||||||
|
' or the file used previously to fill an existing template dir')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
local_config_file = None
|
local_config_file = None
|
||||||
|
orig_config_file = args.original_config
|
||||||
tmpl_dir = None
|
tmpl_dir = None
|
||||||
|
|
||||||
for src in args.sources:
|
for src in args.sources:
|
||||||
|
@ -37,6 +43,12 @@ for src in args.sources:
|
||||||
if local_config_file is None and os.path.isfile(LAST_LOCAL_CONFIG_FILE):
|
if local_config_file is None and os.path.isfile(LAST_LOCAL_CONFIG_FILE):
|
||||||
local_config_file = open(LAST_LOCAL_CONFIG_FILE).read().strip()
|
local_config_file = open(LAST_LOCAL_CONFIG_FILE).read().strip()
|
||||||
|
|
||||||
|
if orig_config_file is None:
|
||||||
|
if os.path.isfile(LAST_ORIG_CONFIG_FILE):
|
||||||
|
orig_config_file = open(LAST_ORIG_CONFIG_FILE).read().strip()
|
||||||
|
else:
|
||||||
|
orig_config_file = DEFAULT_ORIG_CONFIG
|
||||||
|
|
||||||
if tmpl_dir is None and os.path.isfile(LAST_TMPL_DIR):
|
if tmpl_dir is None and os.path.isfile(LAST_TMPL_DIR):
|
||||||
tmpl_dir = open(LAST_TMPL_DIR).read().strip()
|
tmpl_dir = open(LAST_TMPL_DIR).read().strip()
|
||||||
|
|
||||||
|
@ -48,47 +60,57 @@ if not local_config_file or not os.path.isfile(local_config_file):
|
||||||
print("No such config file: %r" % local_config_file)
|
print("No such config file: %r" % local_config_file)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
if not os.path.isfile(orig_config_file):
|
||||||
|
print("No such config file: %r" % orig_config_file)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
local_config_file = os.path.realpath(local_config_file)
|
local_config_file = os.path.realpath(local_config_file)
|
||||||
tmpl_dir = os.path.realpath(tmpl_dir)
|
tmpl_dir = os.path.realpath(tmpl_dir)
|
||||||
net_dir = os.path.realpath(".")
|
net_dir = os.path.realpath(".")
|
||||||
|
|
||||||
print(f'using config file: {local_config_file}')
|
print(f'using config file: {local_config_file}')
|
||||||
|
print(f'with original: {orig_config_file}')
|
||||||
print(f'on templates: {tmpl_dir}')
|
print(f'on templates: {tmpl_dir}')
|
||||||
print(f'with NET_DIR: {net_dir}')
|
print(f'with NET_DIR: {net_dir}')
|
||||||
|
|
||||||
with open(LAST_LOCAL_CONFIG_FILE, 'w') as last_file:
|
with open(LAST_LOCAL_CONFIG_FILE, 'w') as last_file:
|
||||||
last_file.write(local_config_file)
|
last_file.write(local_config_file)
|
||||||
|
with open(LAST_ORIG_CONFIG_FILE, 'w') as last_file:
|
||||||
|
last_file.write(orig_config_file)
|
||||||
with open(LAST_TMPL_DIR, 'w') as last_file:
|
with open(LAST_TMPL_DIR, 'w') as last_file:
|
||||||
last_file.write(tmpl_dir)
|
last_file.write(tmpl_dir)
|
||||||
|
|
||||||
# read in variable values from config file
|
# read in variable values from config files
|
||||||
# NET_DIR is the folder where fill_config.py was started
|
# NET_DIR is the folder where fill_config.py was started
|
||||||
local_config = {"NET_DIR": net_dir}
|
local_config = {"NET_DIR": net_dir}
|
||||||
|
|
||||||
line_nr = 0
|
for config_file in [orig_config_file, local_config_file]:
|
||||||
for line in open(local_config_file):
|
current_config_identifiers = ["NET_DIR"]
|
||||||
line_nr += 1
|
line_nr = 0
|
||||||
line = line.strip('\n')
|
for line in open(config_file):
|
||||||
|
line_nr += 1
|
||||||
|
line = line.strip('\n')
|
||||||
|
|
||||||
if line.startswith('#'):
|
if line.startswith('#'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not '=' in line:
|
if not '=' in line:
|
||||||
if line:
|
if line:
|
||||||
print("Error: %r line %d: %r" % (local_config_file, line_nr, line))
|
print("Error: %r line %d: %r" % (config_file, line_nr, line))
|
||||||
exit(1)
|
exit(1)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
split_pos = line.find('=')
|
split_pos = line.find('=')
|
||||||
name = line[:split_pos]
|
name = line[:split_pos]
|
||||||
val = line[split_pos + 1:]
|
val = line[split_pos + 1:]
|
||||||
|
|
||||||
if val.startswith('"') and val.endswith('"'):
|
if val.startswith('"') and val.endswith('"'):
|
||||||
val = val[1:-1]
|
val = val[1:-1]
|
||||||
|
|
||||||
if name in local_config:
|
if name in current_config_identifiers:
|
||||||
print("Error: duplicate identifier in %r line %d: %r" % (local_config_file, line_nr, line))
|
print("Error: duplicate identifier in %r line %d: %r" % (config_file, line_nr, line))
|
||||||
local_config[name] = val
|
local_config[name] = val
|
||||||
|
current_config_identifiers += [name]
|
||||||
|
|
||||||
# replace variable names with above values recursively
|
# replace variable names with above values recursively
|
||||||
replace_re = re.compile('\$\{([A-Z_][A-Za-z0-9_]*)\}')
|
replace_re = re.compile('\$\{([A-Z_][A-Za-z0-9_]*)\}')
|
||||||
|
@ -240,6 +262,7 @@ for tmpl_name in sorted(os.listdir(tmpl_dir)):
|
||||||
|
|
||||||
if args.check_stale:
|
if args.check_stale:
|
||||||
check_stale(local_config_file, dst)
|
check_stale(local_config_file, dst)
|
||||||
|
check_stale(orig_config_file, dst)
|
||||||
check_stale(tmpl_src, dst)
|
check_stale(tmpl_src, dst)
|
||||||
|
|
||||||
local_config['_fname'] = tmpl_name
|
local_config['_fname'] = tmpl_name
|
||||||
|
|
Loading…
Reference in New Issue