Browse Source

Minor changes and additions

main
Nocturn9x 2 months ago
parent
commit
7b7b675fef
  1. 4
      scripts/boot.sh
  2. 19
      scripts/start.sh
  3. 15
      src/core/control.nim
  4. 17
      src/core/fs.nim
  5. 6
      src/core/mainloop.nim
  6. 3
      src/core/services.nim
  7. 2
      src/main.nim
  8. 11
      src/programs/halt.nim
  9. 11
      src/programs/poweroff.nim
  10. 11
      src/programs/reboot.nim
  11. 30
      src/programs/reload.nim
  12. 30
      src/util/cffi.nim
  13. 7
      src/util/logging.nim
  14. 20
      src/util/misc.nim

4
scripts/boot.sh

@ -107,9 +107,9 @@ then
fi
qemumem=''
if ! [[ $memory -eq "" ]]
if ! [[ ${memory::-1} -eq "" ]]
then
qemumem="-m ${memory}"
fi
qemu-system-x86_64 -net nic,model=virtio,netdev=user.0 -netdev user,id=user.0 -drive file=vm.qcow2,if=virtio -enable-kvm -kernel ${kernel} -initrd ${initrd} ${qemumem} -append 'root=/dev/vda1 rw quiet modules=ext4 console=ttyS0 init=/bin/nimd'
qemu-system-x86_64 -net nic,model=virtio,netdev=user.0 -netdev user,id=user.0 -drive file=vm.qcow2,if=virtio -enable-kvm -kernel ${kernel} -initrd ${initrd} ${qemumem} -append 'root=/dev/vda1 rw quiet modules=ext4 init=/sbin/nimd console=ttyS0 -- -X'

19
scripts/start.sh

@ -1 +1,18 @@
./scripts/boot.sh --kernel vmlinuz-linux --initrd initrd-linux.img --memory 1G
trap 'catch' ERR
catch() {
echo "Build failed"
exit
}
echo "Compiling NimD"
nim -d:release -d:danger --passC:"-O3 -flto" --opt:size --hints:off --gc:orc --passL:"-static" -o:rootfs/sbin/nimd c src/main
echo "Compiling NimD subprograms"
nim -d:release -d:danger --passC:"-O3 -flto" --opt:size --hints:off --gc:orc --passL:"-static" -o:rootfs/sbin/poweroff c src/programs/poweroff
nim -d:release -d:danger --passC:"-O3 -flto" --opt:size --hints:off --gc:orc --passL:"-static" -o:rootfs/sbin/halt c src/programs/halt
nim -d:release -d:danger --passC:"-O3 -flto" --opt:size --hints:off --gc:orc --passL:"-static" -o:rootfs/sbin/reboot c src/programs/reboot
nim -d:release -d:danger --passC:"-O3 -flto" --opt:size --hints:off --gc:orc --passL:"-static" -o:rootfs/sbin/nimd-reload c src/programs/reload
echo "Setting up directory structure"
mkdir -p rootfs/etc/nimd
cp nimd.conf rootfs/etc/nimd
echo "Building and starting VM"
./boot.sh --memory 1G --kernel vmlinuz-linux --initrd initramfs-linux.img --build

15
src/core/control.nim

@ -13,24 +13,31 @@
# limitations under the License.
import os
import net
import posix
import strformat
import shutdown
import ../util/logging
import ../util/misc
proc initControlSocket*(logger: Logger, path: string = "/var/run/nimd.sock"): Socket =
## Initializes NimD's control socket (an unbuffered
## TCP Unix Domain Socket) binding it to the given
## path (defaults to /var/run/nimd.sock)
## path (defaults to /var/run/nimd.sock). The socket's
## permissions are set to 700 so that only root can read
## from it
try:
logger.info(&"Initializing control socket at '{path}'")
if exists(path):
if fileExists(path):
removeFile(path)
result = newSocket(AF_UNIX, SOCK_STREAM, IPPROTO_IP, buffered=false)
elif dirExists(path):
removeDir(path)
result = newSocket(net.AF_UNIX, net.SOCK_STREAM, net.IPPROTO_IP, buffered=false)
bindUnix(result, path)
if posix.chmod(cstring(splitPath(path).head), 700) == -1:
logger.error(&"Could not restrict access to unix socket at '{path}: {posix.strerror(posix.errno)}'")
nimDExit(logger, code=int(posix.errno))
except OSError:
logger.error(&"Error when binding unix socket at '{path}': {getCurrentExceptionMsg()}")
nimDExit(logger, code=int(osLastError()))

17
src/core/fs.nim

@ -17,25 +17,10 @@ import strformat
import posix
import os
import ../util/[logging, misc]
import ../util/[logging, misc, cffi]
import shutdown
# Nim wrappers around C functionality in sys/mount.h on Linux
proc mount*(source: cstring, target: cstring, fstype: cstring,
mountflags: culong, data: pointer): cint {.header: "sys/mount.h", importc.}
# Since cstrings are weak references, we need to convert nim strings to cstrings only
# when we're ready to use them and only when we're sure the underlying nim string is
# in scope, otherwise garbage collection madness happens
proc mount*(source, target, fstype: string, mountflags: uint64, data: string): int = int(mount(cstring(source), cstring(target), cstring(fstype), culong(mountflags), cstring(data)))
proc umount*(target: cstring): cint {.header: "sys/mount.h", importc.}
proc umount2*(target: cstring, flags: cint): cint {.header: "sys/mount.h", importc.}
# These 2 wrappers silent the CStringConv warning
# (implicit conversion to 'cstring' from a non-const location)
proc umount*(target: string): int = int(umount(cstring(target)))
proc umount2*(target: string, flags: int): int = int(umount2(cstring(target), cint(flags)))
## Our Nim API
type

6
src/core/mainloop.nim

@ -28,9 +28,9 @@ proc mainLoop*(logger: Logger, config: NimDConfig, startServices: bool = true) =
if startServices:
logger.info("Processing default runlevel")
startServices(logger, workers=config.workers, level=Default)
logger.debug(&"Unblocking signals")
unblockSignals(logger)
logger.info("System initialization complete, idling on control socket")
logger.debug(&"Unblocking signals")
unblockSignals(logger)
logger.info("System initialization complete, idling on control socket")
var opType: string
try:
logger.trace("Calling initControlSocket()")

3
src/core/services.nim

@ -22,10 +22,9 @@ import shlex
import os
proc strsignal(sig: cint): cstring {.header: "string.h", importc.}
import ../util/logging
import ../util/cffi
type

2
src/main.nim

@ -18,7 +18,7 @@ import net
import os
# NimD's own stuff
import util/[logging, constants, misc, config]
import util/[logging, constants, misc, config, cffi]
import core/[mainloop, fs, shutdown, services]

11
src/programs/halt.nim

@ -11,7 +11,9 @@
# 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 os
import net
import strformat
when isMainModule:
@ -19,7 +21,10 @@ when isMainModule:
try:
sock.connectUnix("/var/run/nimd.sock")
except OSError:
echo getCurrentExceptionMsg()
quit(-1)
echo sock.trySend("r")
echo &"Communication with NimD control socket failed: {osErrorMsg(osLastError())}"
quit(int(osLastError()))
if sock.trySend("h"):
echo "Halting"
else:
echo &"Communication with NimD control socket failed: {osErrorMsg(osLastError())}"
sock.close()

11
src/programs/poweroff.nim

@ -11,7 +11,9 @@
# 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 os
import net
import strformat
when isMainModule:
@ -19,7 +21,10 @@ when isMainModule:
try:
sock.connectUnix("/var/run/nimd.sock")
except OSError:
echo getCurrentExceptionMsg()
quit(-1)
echo sock.trySend("p")
echo &"Communication with NimD control socket failed: {osErrorMsg(osLastError())}"
quit(int(osLastError()))
if sock.trySend("p"):
echo "Shutting down"
else:
echo &"Communication with NimD control socket failed: {osErrorMsg(osLastError())}"
sock.close()

11
src/programs/reboot.nim

@ -11,7 +11,9 @@
# 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 os
import net
import strformat
when isMainModule:
@ -19,7 +21,10 @@ when isMainModule:
try:
sock.connectUnix("/var/run/nimd.sock")
except OSError:
echo getCurrentExceptionMsg()
quit(-1)
echo sock.trySend("r")
echo &"Communication with NimD control socket failed: {osErrorMsg(osLastError())}"
quit(int(osLastError()))
if sock.trySend("r"):
echo "Rebooting"
else:
echo &"Communication with NimD control socket failed: {osErrorMsg(osLastError())}"
sock.close()

30
src/programs/reload.nim

@ -0,0 +1,30 @@
# 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 os
import net
import strformat
when isMainModule:
var sock = newSocket(AF_UNIX, SOCK_STREAM, IPPROTO_IP)
try:
sock.connectUnix("/var/run/nimd.sock")
except OSError:
echo &"Communication with NimD control socket failed: {osErrorMsg(osLastError())}"
quit(int(osLastError()))
if sock.trySend("l"):
echo "Reloading"
else:
echo &"Communication with NimD control socket failed: {osErrorMsg(osLastError())}"
sock.close()

30
src/util/cffi.nim

@ -0,0 +1,30 @@
# 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.
proc strsignal*(sig: cint): cstring {.header: "string.h", importc.}
proc dup3*(a1, a2, a3: cint): cint {.importc.}
# Nim wrappers around C functionality in sys/mount.h on Linux
proc mount*(source: cstring, target: cstring, fstype: cstring,
mountflags: culong, data: pointer): cint {.header: "sys/mount.h", importc.}
# Since cstrings are weak references, we need to convert nim strings to cstrings only
# when we're ready to use them and only when we're sure the underlying nim string is
# in scope, otherwise garbage collection madness happens
proc mount*(source, target, fstype: string, mountflags: uint64, data: string): int = int(mount(cstring(source), cstring(target), cstring(fstype), culong(mountflags), cstring(data)))
proc umount*(target: cstring): cint {.header: "sys/mount.h", importc.}
proc umount2*(target: cstring, flags: cint): cint {.header: "sys/mount.h", importc.}
# These 2 wrappers silent the CStringConv warning
# (implicit conversion to 'cstring' from a non-const location)
proc umount*(target: string): int = int(umount(cstring(target)))
proc umount2*(target: string, flags: int): int = int(umount2(cstring(target), cint(flags)))

7
src/util/logging.nim

@ -19,6 +19,8 @@ import posix
import times
import cffi
type
LogLevel* = enum
Trace = 0,
@ -39,9 +41,6 @@ type
handlers*: seq[LogHandler]
proc dup3(a1, a2, a3: cint): cint {.importc.}
var defaultLevel = LogLevel.Info
var logFile = "/var/log/nimd"
var logToFileOnly: bool = false
@ -215,7 +214,7 @@ proc switchToConsole*(self: Logger) =
self.addHandler(createHandler(logFatalStderr, LogLevel.Fatal))
proc getDefaultLogger*(): Logger =
proc getDefaultLogger*: Logger =
## Gets a simple logger with level set
## to LogLevel.Info and one handler per
## level that writes the given message to the

20
src/util/misc.nim

@ -26,7 +26,6 @@ import ../core/shutdown
proc sleepSeconds*(amount: SomeNumber) = sleep(int(amount * 1000))
proc strsignal*(sig: cint): cstring {.header: "string.h", importc.}
proc dummySigHandler(x: cint) {.noconv.} = discard
@ -80,15 +79,6 @@ proc reapProcess*(logger: Logger) =
logger.trace(&"Call to waitpid() set status to {status} and returned {returnCode}")
proc exists*(p: string): bool =
## Returns true if a path exists,
## false otherwise
try:
discard getFileInfo(p)
result = true
except OSError:
result = false
proc setHostname*(logger: Logger): string =
## Sets the machine's hostname. Returns
@ -108,3 +98,13 @@ proc setHostname*(logger: Logger): string =
logger.error(&"An error occurred while setting hostname -> {getCurrentExceptionMsg()}")
return ""
return hostname
proc exists*(p: string): bool =
## Returns true if a path exists,
## false otherwise
try:
discard getFileInfo(p)
result = true
except OSError:
result = false
Loading…
Cancel
Save