[hostcfgd] Get service enable/disable feature working (#4676)

Fix hostcfgd so that changes to the "FEATURE" table in ConfigDB are properly handled. Three changes here:

1. Fix indenting such that the handling of each key actually occurs in the for key in status_data.keys(): loop
2. Add calls to sudo systemctl mask and sudo systemctl unmask as appropriate to ensure changes persist across reboots
3. Substitute returns with continues so that even if one service fails, we still try to handle the others

Note that the masking is persistent, even if the configuration is not saved. We may want to consider only calling systemctl enable/disable in hostcfgd when the DB table changes, and only call systemctl mask/unmask upon calling config save.
This commit is contained in:
Joe LeVeque 2020-06-02 02:07:22 -07:00 committed by Abhishek Dosi
parent 42bc14f44c
commit ed0e6aed1c

View File

@ -267,39 +267,42 @@ class HostConfigDaemon:
for key in status_data.keys(): for key in status_data.keys():
if not key: if not key:
syslog.syslog(syslog.LOG_WARNING, "FEATURE key is missing") syslog.syslog(syslog.LOG_WARNING, "FEATURE key is missing")
return continue
status = status_data[key]['status']
if not status: status = status_data[key]['status']
syslog.syslog(syslog.LOG_WARNING, "status is missing for {}".format(key)) if not status:
return syslog.syslog(syslog.LOG_WARNING, "status is missing for {}".format(key))
if status == "enabled": continue
start_cmds=[] if status == "enabled":
start_cmds.append("sudo systemctl enable {}".format(key)) start_cmds=[]
start_cmds.append("sudo systemctl start {}".format(key)) start_cmds.append("sudo systemctl unmask {}.service".format(key))
for cmd in start_cmds: start_cmds.append("sudo systemctl enable {}.service".format(key))
syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) start_cmds.append("sudo systemctl start {}.service".format(key))
try: for cmd in start_cmds:
subprocess.check_call(cmd, shell=True) syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd))
except subprocess.CalledProcessError as err: try:
syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" subprocess.check_call(cmd, shell=True)
.format(err.cmd, err.returncode, err.output)) except subprocess.CalledProcessError as err:
return syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}"
syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(key)) .format(err.cmd, err.returncode, err.output))
elif status == "disabled": continue
stop_cmds=[] syslog.syslog(syslog.LOG_INFO, "Feature '{}' is enabled and started".format(key))
stop_cmds.append("sudo systemctl stop {}".format(key)) elif status == "disabled":
stop_cmds.append("sudo systemctl disable {}".format(key)) stop_cmds=[]
for cmd in stop_cmds: stop_cmds.append("sudo systemctl stop {}.service".format(key))
syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd)) stop_cmds.append("sudo systemctl disable {}.service".format(key))
try: stop_cmds.append("sudo systemctl mask {}.service".format(key))
subprocess.check_call(cmd, shell=True) for cmd in stop_cmds:
except subprocess.CalledProcessError as err: syslog.syslog(syslog.LOG_INFO, "Running cmd - {}".format(cmd))
syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}" try:
.format(err.cmd, err.returncode, err.output)) subprocess.check_call(cmd, shell=True)
return except subprocess.CalledProcessError as err:
syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(key)) syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}"
else: .format(err.cmd, err.returncode, err.output))
syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for '{}'".format(status, key)) continue
syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(key))
else:
syslog.syslog(syslog.LOG_ERR, "Unexpected status value '{}' for '{}'".format(status, key))
def start(self): def start(self):
self.config_db.subscribe('AAA', lambda table, key, data: self.aaa_handler(key, data)) self.config_db.subscribe('AAA', lambda table, key, data: self.aaa_handler(key, data))