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.