2021-11-30 23:56:38 +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.
import strformat
2021-12-05 22:08:08 +01:00
import os
2021-12-27 11:17:24 +01:00
import net
2021-11-30 23:56:38 +01:00
2021-12-04 17:31:18 +01:00
2022-01-09 22:46:25 +01:00
import .. / util / [ logging , misc , config ]
2021-12-04 13:47:06 +01:00
import services
2021-12-27 11:17:24 +01:00
import control
import shutdown
2021-11-30 23:56:38 +01:00
2021-12-04 13:47:06 +01:00
2022-01-09 22:46:25 +01:00
proc mainLoop * ( logger : Logger , config : NimDConfig , startServices : bool = true ) =
2021-11-30 23:56:38 +01:00
## NimD's main execution loop
2022-01-04 12:00:18 +01:00
if startServices :
logger . info ( " Processing default runlevel " )
2022-01-09 22:46:25 +01:00
startServices ( logger , workers = config . workers , level = Default )
2022-01-04 12:00:18 +01:00
logger . debug ( & " Unblocking signals " )
unblockSignals ( logger )
2021-12-27 11:18:42 +01:00
logger . info ( " System initialization complete, idling on control socket " )
2021-12-27 11:17:24 +01:00
var opType : string
2021-12-05 22:08:08 +01:00
try :
2021-12-27 11:17:24 +01:00
logger . trace ( " Calling initControlSocket() " )
2022-01-31 14:56:12 +01:00
var serverSocket = initControlSocket ( logger , config . sock )
2021-12-27 11:17:24 +01:00
serverSocket . listen ( 5 )
var clientSocket = newSocket ( AF_INET , SOCK_STREAM , IPPROTO_TCP )
2021-12-27 11:18:42 +01:00
logger . switchToFile ( )
2022-01-04 12:00:18 +01:00
logger . debug ( " Entering accept() loop " )
2021-12-05 22:08:08 +01:00
while true :
2021-12-27 11:17:24 +01:00
serverSocket . accept ( clientSocket )
2022-01-04 12:00:18 +01:00
logger . debug ( & " Received connection on control socket " )
2021-12-27 11:17:24 +01:00
if clientSocket . recv ( opType , size = 1 ) = = 0 :
2022-01-04 12:00:18 +01:00
logger . debug ( & " Client has disconnected, waiting for new connections " )
2021-12-27 11:17:24 +01:00
continue
logger . debug ( & " Received operation type ' {opType} ' via control socket " )
# The operation type is a single byte:
# - 'p' -> poweroff
# - 'r' -> reboot
# - 'h' -> halt
# - 's' -> Services-related operations (start, stop, get status, etc.)
case opType :
of " p " :
logger . info ( " Received shutdown request " )
shutdown ( logger )
of " r " :
logger . info ( " Received reboot request " )
reboot ( logger )
of " h " :
logger . info ( " Received halt request " )
halt ( logger )
of " s " :
2022-01-31 14:56:12 +01:00
logger . info ( " Received service request " )
# TODO: Operate on services
of " l " :
logger . info ( " Received reload request " )
mainLoop ( logger , parseConfig ( logger , " /etc/nimd/nimd.conf " ) , startServices = false )
2021-12-27 11:17:24 +01:00
else :
logger . warning ( & " Received unknown operation type ' {opType} ' via control socket, ignoring it " )
discard
clientSocket . close ( )
2021-12-05 22:08:08 +01:00
except :
2022-01-09 22:46:25 +01:00
logger . critical ( & " A critical error has occurred while running, restarting the mainloop in {config.restartDelay} seconds! Error -> {getCurrentExceptionMsg()} " )
sleepSeconds ( config . restartDelay )
2021-12-05 22:08:08 +01:00
# We *absolutely* cannot die
2022-01-09 22:46:25 +01:00
mainLoop ( logger , config , startServices = false )