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.