228 lines
6.9 KiB
Python
228 lines
6.9 KiB
Python
from __future__ import absolute_import, division, print_function
|
|
|
|
import os
|
|
import glob
|
|
import re
|
|
import seiscomp.kernel
|
|
import seiscomp.config
|
|
import seiscomp.system
|
|
|
|
|
|
class Module(seiscomp.kernel.Module):
|
|
def __init__(self, env):
|
|
seiscomp.kernel.Module.__init__(self, env, env.moduleName(__file__))
|
|
self.config_dir = os.path.join(self.env.SEISCOMP_ROOT, "var", "lib")
|
|
self.log_dir = os.path.join(self.env.SEISCOMP_ROOT, "var", "log")
|
|
|
|
def _run(self):
|
|
if self.env.syslog:
|
|
daemon_opt = "-s"
|
|
else:
|
|
daemon_opt = "--log-file " + os.path.join(
|
|
self.log_dir, self.name + ".log"
|
|
)
|
|
|
|
daemon_opt += " -f " + os.path.join(
|
|
self.config_dir, self.name + ".cfg"
|
|
)
|
|
|
|
prog = "run_with_lock"
|
|
params = self.env.lockFile(self.name)
|
|
|
|
return self.env.start(
|
|
self.name,
|
|
prog,
|
|
params + " " + self.env.binaryFile(self.name) + " " + daemon_opt,
|
|
True,
|
|
)
|
|
|
|
def supportsAliases(self):
|
|
return True
|
|
|
|
def updateConfig(self):
|
|
bindings_dir = os.path.join(self.env.SEISCOMP_ROOT, "etc", "key")
|
|
key_dir = os.path.join(bindings_dir, self.name)
|
|
cfg_file = os.path.join(self.config_dir, self.name + ".cfg")
|
|
rx_binding = re.compile(
|
|
r"(?P<module>[A-Za-z0-9_\.-]+)(:(?P<profile>[A-Za-z0-9_-]+))?$"
|
|
)
|
|
|
|
files = sorted(glob.glob(os.path.join(bindings_dir, "station_*")))
|
|
|
|
try:
|
|
fb = open(cfg_file, "w", encoding="utf-8")
|
|
except BaseException:
|
|
print(f"error: unable to generate configuration file '{cfg_file}'")
|
|
return 1
|
|
|
|
cfg = seiscomp.config.Config()
|
|
|
|
try:
|
|
# Defaults Global + App Cfg
|
|
cfg.readConfig(
|
|
os.path.join(
|
|
self.env.SEISCOMP_ROOT, "etc", "defaults", "global.cfg"
|
|
)
|
|
)
|
|
cfg.readConfig(
|
|
os.path.join(
|
|
self.env.SEISCOMP_ROOT,
|
|
"etc",
|
|
"defaults",
|
|
self.name + ".cfg",
|
|
)
|
|
)
|
|
|
|
# Config Global + App Cfg
|
|
cfg.readConfig(
|
|
os.path.join(self.env.SEISCOMP_ROOT, "etc", "global.cfg")
|
|
)
|
|
cfg.readConfig(
|
|
os.path.join(self.env.SEISCOMP_ROOT, "etc", self.name + ".cfg")
|
|
)
|
|
|
|
# User Global + App Cfg
|
|
cfg.readConfig(
|
|
os.path.join(os.environ["HOME"], ".seiscomp", "global.cfg")
|
|
)
|
|
cfg.readConfig(
|
|
os.path.join(
|
|
os.environ["HOME"], ".seiscomp", self.name + ".cfg"
|
|
)
|
|
)
|
|
except BaseException:
|
|
pass
|
|
|
|
try:
|
|
print(f"queue_size = {cfg.getInt('queueSize')}", file=fb)
|
|
except BaseException:
|
|
pass
|
|
|
|
try:
|
|
print(
|
|
f"backfilling_buffer_size = {cfg.getInt('backFillingBufferSize')}",
|
|
file=fb,
|
|
)
|
|
except BaseException:
|
|
pass
|
|
|
|
has_channel_mappings = False
|
|
|
|
try:
|
|
print(
|
|
f"channels = {', '.join(cfg.getStrings('channels'))}",
|
|
file=fb,
|
|
)
|
|
has_channel_mappings = True
|
|
except BaseException:
|
|
pass
|
|
|
|
try:
|
|
default_address = cfg.getString("address")
|
|
except BaseException:
|
|
default_address = None
|
|
|
|
try:
|
|
default_sink = cfg.getString("sink")
|
|
except BaseException:
|
|
default_sink = None
|
|
|
|
units = {}
|
|
|
|
for f in files:
|
|
try:
|
|
(path, net, sta) = os.path.basename(f).split("_")
|
|
if not path.endswith("station"):
|
|
print("invalid path", f)
|
|
|
|
except ValueError:
|
|
print("invalid path", f)
|
|
continue
|
|
|
|
fd = open(f, encoding="utf-8")
|
|
line = fd.readline()
|
|
while line:
|
|
line = line.strip()
|
|
if not line or line[0] == "#":
|
|
line = fd.readline()
|
|
continue
|
|
|
|
m = rx_binding.match(line)
|
|
if not m:
|
|
# print("invalid binding in %s: %s" % (f, line))
|
|
line = fd.readline()
|
|
continue
|
|
|
|
if m.group("module") != self.name:
|
|
line = fd.readline()
|
|
continue
|
|
|
|
profile = m.group("profile")
|
|
|
|
# Setup station net, sta, profile
|
|
if profile:
|
|
binding_file = f"profile_{profile}"
|
|
else:
|
|
binding_file = f"station_{net}_{sta}"
|
|
|
|
cfg = seiscomp.config.Config()
|
|
cfg.readConfig(os.path.join(key_dir, binding_file))
|
|
try:
|
|
unit = cfg.getString("unit")
|
|
except BaseException:
|
|
print(f"warning: unit is not defined in {binding_file}")
|
|
break
|
|
|
|
try:
|
|
channels = cfg.getStrings("channels")
|
|
except BaseException:
|
|
if not has_channel_mappings:
|
|
print(
|
|
f"warning: channel mappings are not defined in {binding_file}"
|
|
)
|
|
break
|
|
channels = None
|
|
|
|
try:
|
|
address = cfg.getString("address")
|
|
except BaseException:
|
|
if default_address is None:
|
|
print(
|
|
f"warning: address not defined in {binding_file}"
|
|
)
|
|
break
|
|
address = default_address
|
|
|
|
try:
|
|
sink = cfg.getString("sink")
|
|
except BaseException:
|
|
if default_sink is None:
|
|
print(f"warning: sink not defined in {binding_file}")
|
|
break
|
|
sink = default_sink
|
|
|
|
if unit in units:
|
|
print(
|
|
f"error: unit {unit} is bound to multiple stations "
|
|
f"({units[unit][0]}.{units[unit][1]}, {net}.{sta}, ...)"
|
|
)
|
|
return 1
|
|
|
|
units[unit] = (net, sta)
|
|
|
|
print(f"unit {unit}", file=fb)
|
|
print(f' network = "{net}"', file=fb)
|
|
print(f' station = "{sta}"', file=fb)
|
|
if channels is not None:
|
|
print(f" channels = {', '.join(channels)}", file=fb)
|
|
print(f" address = {address}", file=fb)
|
|
print(f" sink = {sink}", file=fb)
|
|
|
|
break
|
|
|
|
fd.close()
|
|
|
|
fb.close()
|
|
|
|
return 0
|