summaryrefslogtreecommitdiffstats
path: root/crmsh/service_manager.py
blob: 3d51e9408d7db7c1ee6918c36ed6a8c5f990f406 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import typing

import crmsh.parallax
import crmsh.sh


class ServiceManager(object):
    """
    Class to manage systemctl services
    """

    def __init__(self, shell: crmsh.sh.ClusterShell = None):
        self._shell = crmsh.sh.cluster_shell() if shell is None else shell

    def service_is_available(self, name, remote_addr=None):
        """
        Check whether service is available
        """
        return 0 == self._run_on_single_host("systemctl list-unit-files '{}'".format(name), remote_addr)

    def service_is_enabled(self, name, remote_addr=None):
        """
        Check whether service is enabled
        """
        return 0 == self._run_on_single_host("systemctl is-enabled '{}'".format(name), remote_addr)

    def service_is_active(self, name, remote_addr=None):
        """
        Check whether service is active
        """
        return 0 == self._run_on_single_host("systemctl is-active '{}'".format(name), remote_addr)

    def start_service(self, name, enable=False, remote_addr=None, node_list=[]):
        """
        Start service
        Return success node list
        """
        if enable:
            cmd = "systemctl enable --now '{}'".format(name)
        else:
            cmd = "systemctl start '{}'".format(name)
        return self._call(remote_addr, node_list, cmd)

    def _call(self, remote_addr: str, node_list: typing.List[str], cmd: str) -> typing.List[str]:
        assert not (bool(remote_addr) and bool(node_list))
        if len(node_list) == 1:
            remote_addr = node_list[0]
            node_list = list()
        if node_list:
            results = ServiceManager._call_with_parallax(cmd, node_list)
            return [host for host, result in results.items() if isinstance(result, tuple) and result[0] == 0]
        else:
            rc = self._run_on_single_host(cmd, remote_addr)
            if rc == 0:
                return [remote_addr]
            else:
                return list()

    def _run_on_single_host(self, cmd, host):
        rc, _, _ = self._shell.get_rc_stdout_stderr_without_input(host, cmd)
        if rc == 255:
            raise ValueError("Failed to run command on host {}: {}".format(host, cmd))
        return rc

    @staticmethod
    def _call_with_parallax(cmd, host_list):
        ret = crmsh.parallax.parallax_run(host_list, cmd)
        if ret is crmsh.parallax.Error:
            raise ret
        return ret

    def stop_service(self, name, disable=False, remote_addr=None, node_list=[]):
        """
        Stop service
        Return success node list
        """
        if disable:
            cmd = "systemctl disable --now '{}'".format(name)
        else:
            cmd = "systemctl stop '{}'".format(name)
        return self._call(remote_addr, node_list, cmd)

    def enable_service(self, name, remote_addr=None, node_list=[]):
        """
        Enable service
        Return success node list
        """
        cmd = "systemctl enable '{}'".format(name)
        return self._call(remote_addr, node_list, cmd)

    def disable_service(self, name, remote_addr=None, node_list=[]):
        """
        Disable service
        Return success node list
        """
        cmd = "systemctl disable '{}'".format(name)
        return self._call(remote_addr, node_list, cmd)