Created by CecilWesterhof.
In the past I wrote a script to check if systemd services where running and if not tried to restart them. I rewrote this script into Tcl and added some functionalities.
The main code is:
init
foreach service $services {
debugOutput $debug "Checking: $service"
if {! [isServiceActive $service]} {
puts "$service is not running"
giveStatus $service
if {[startService $service]} {
puts " $service started"
} else {
puts " $service NOT started"
giveStatus
}
}
}It checks all the services and if one is not running it tries to start it.
To check if a service is running I use:
proc isServiceActive {service} {
if {[catch {exec systemctl status $service} result]} {
if {([lindex $::errorCode 0] == "CHILDSTATUS") &&
([lindex $::errorCode 2] == 3)} {
return False
}
error $result
}
return True
}The call 'systemctl status SERVICE' returns 0 if the service is running and 3 if it is not running. Anything else is an error.
If the service is not running I give the status:
proc giveStatus {service} {
set status [getCleanOutput "systemctl status $service" {3}]
puts "\nStatus:\n$status"
}Which uses: Getting Cleaned Up Output from a Command.
It then tries to start the service:
proc startService {service} {
puts "\nTrying to start:"
exec systemctl start $service
sleep $::startTime
isServiceActive $service
}If that is successful it says that, otherwise it says it was not successful and displays the status of the service.
The initialisation is done with:
proc init {} {
set ::debug False
set ::startTime 5
set parameters $::argv
switch [lindex $parameters 0] {
--debug {
set ::debug True
set parameters [lrange $parameters 1 end]
}
--active {
puts "Active services:"
foreach service [getServices] {
puts " $service"
}
exit
}
--inactive {
puts "Inactive services:"
foreach service [getServices F] {
puts " $service"
}
exit
}
}
if {[llength $parameters] > 0} {
set ::services $parameters
} else {
set ::services [getServices]
}
}Default the services to check are retrieved from the database, but you can also give them on the command-line. It is possible to activate debugging. And a list with the active or inactive services can be shown.
To get the list with (in)active services:
proc getServices {{active T}} {
getDefaultDB
set services [db eval {
SELECT service
FROM checkServices
WHERE active = :active
ORDER BY service
}]
db close
return $services
}I will share getDefaultDB later.
To create the table:
CREATE TABLE checkServices (
service TEXT PRIMARY KEY,
active TEXT NOT NULL DEFAULT 'T' CHECK(active IN ('T', 'F'))
);To sleep a few seconds (to give the service time to start):
proc sleep {seconds} {
after [expr {$seconds * 1000}]
}The proc debugOutput is very simple:
proc debugOutput {giveOutput Message} {
if {$giveOutput} {
puts $Message
}
}As always: comments, tips and questions are appreciated.