2021-12-06 13:47:11 +01:00
|
|
|
# Copyright 2021 Mattia Giambirtone & All Contributors
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
|
2021-12-16 11:24:00 +01:00
|
|
|
import tables
|
2021-12-06 13:47:11 +01:00
|
|
|
import parsecfg
|
2021-12-16 11:24:00 +01:00
|
|
|
import strutils
|
|
|
|
import strformat
|
2021-12-06 13:47:11 +01:00
|
|
|
|
|
|
|
|
|
|
|
import ../util/logging
|
|
|
|
import services
|
|
|
|
import fs
|
|
|
|
|
|
|
|
|
|
|
|
type
|
2021-12-16 11:24:00 +01:00
|
|
|
NimDConfig* = ref object
|
2021-12-06 13:47:11 +01:00
|
|
|
## Configuration object
|
|
|
|
logLevel*: LogLevel
|
|
|
|
logDir*: Directory
|
|
|
|
services*: tuple[runlevel: RunLevel, services: seq[Service]]
|
2021-12-16 11:24:00 +01:00
|
|
|
directories*: seq[Directory]
|
|
|
|
symlinks*: seq[Symlink]
|
|
|
|
filesystems*: seq[Filesystem]
|
|
|
|
restartDelay*: int
|
|
|
|
autoMount*: bool
|
|
|
|
autoUnmount*: bool
|
|
|
|
fstab*: string
|
|
|
|
sock*: string
|
|
|
|
|
|
|
|
|
|
|
|
const defaultSections = ["Misc", "Logging", "Filesystem"]
|
|
|
|
const defaultConfig = {
|
|
|
|
"Logging": {
|
|
|
|
"stderr": "/var/log/nimd",
|
|
|
|
"stdout": "/var/log/nimd",
|
|
|
|
"level": "info"
|
|
|
|
}.toTable(),
|
|
|
|
"Misc": {
|
|
|
|
"controlSocket": "/var/run/nimd.sock",
|
|
|
|
"onDependencyConflict": "skip"
|
|
|
|
}.toTable(),
|
|
|
|
"Filesystem": {
|
|
|
|
"autoMount": "true",
|
|
|
|
"autoUnmount": "true",
|
|
|
|
"fstabPath": "/etc/fstab",
|
|
|
|
"createDirs": "",
|
|
|
|
"createSymlinks": "",
|
|
|
|
"virtualDisks": ""
|
|
|
|
}.toTable()
|
|
|
|
}.toTable()
|
|
|
|
const levels = {"trace": Trace, "debug": Debug, "info": Info,
|
|
|
|
"warning": Warning, "error": Error, "critical": Critical,
|
|
|
|
"fatal": Fatal}.toTable()
|
|
|
|
|
|
|
|
|
|
|
|
proc parseConfig*(logger: Logger, file: string = "/etc/nimd/nimd.conf"): NimDConfig =
|
|
|
|
## Parses NimD's configuration file
|
|
|
|
## and returns a configuration object
|
|
|
|
|
|
|
|
# Yes this code is far from perfect, but I hate paesing
|
|
|
|
# config files :(
|
|
|
|
logger.debug(&"Reading config file at {file}")
|
|
|
|
let cfgObject = loadConfig(file)
|
|
|
|
var data = newTable[string, TableRef[string, string]]()
|
|
|
|
var existingSections: seq[string] = @[]
|
|
|
|
var directories: seq[Directory] = @[]
|
|
|
|
var filesystems: seq[Filesystem] = @[]
|
|
|
|
var symlinks: seq[Symlink] = @[]
|
|
|
|
var temp: seq[string] = @[]
|
|
|
|
for section in cfgObject.sections():
|
|
|
|
existingSections.add(section)
|
|
|
|
for section in defaultSections:
|
|
|
|
logger.debug(&"Parsing section '{section}'")
|
|
|
|
if section notin existingSections:
|
|
|
|
logger.warning(&"Missing section '{section}' from config file, falling back to defaults")
|
|
|
|
for (value, key) in defaultConfig[section].pairs():
|
|
|
|
data[section][value] = key
|
|
|
|
elif section notin defaultSections:
|
|
|
|
logger.warning(&"Unknown section '{section}' found in config file, skipping it")
|
|
|
|
else:
|
|
|
|
for key in defaultConfig[section].keys():
|
|
|
|
data[section][key] = cfgObject.getSectionValue(section, key, defaultConfig[section][key])
|
|
|
|
for dirInfo in data["Filesystem"]["createDirs"].split(","):
|
|
|
|
temp = dirInfo.split(":")
|
|
|
|
directories.add(newDirectory(temp[0], uint64(parseInt(temp[1]))))
|
|
|
|
for symInfo in data["Filesystem"]["createSymlinks"].split(","):
|
|
|
|
temp = symInfo.split(":")
|
|
|
|
symlinks.add(newSymlink(temp[0], temp[1]))
|
|
|
|
if data["Logging"]["level"] notin levels:
|
|
|
|
logger.warning(&"""Unknown logging level '{data["Logging"]["level"]}', defaulting to {defaultConfig["Logging"]["level"]}""")
|
|
|
|
data["Logging"]["level"] = defaultConfig["Logging"]["level"]
|
|
|
|
result = NimDConfig(logLevel: levels[data["Logging"]["level"]],
|
|
|
|
filesystems: filesystems)
|