# Buggy code
def get_hwclock():
    """
    Get current hardware clock setting (UTC or localtime)

    CLI Example:

    .. code-block:: bash

        salt '*' timezone.get_hwclock
    """
    cmd = ""
    if salt.utils.which("timedatectl"):
        out = __salt__["cmd.run"](["timedatectl"], python_shell=False)
        for line in (x.strip() for x in out.splitlines()):
            if "rtc in local tz" in line.lower():
                try:
                    if line.split(":")[-1].strip().lower() == "yes":
                        return "localtime"
                    else:
                        return "UTC"
                except IndexError:
                    pass
        raise CommandExecutionError(
            "Failed to parse timedatectl output, this is likely a bug"
        )
    else:
        os_family = __grains__["os_family"]
        for family in ("RedHat", "Suse"):
            if family in os_family:
                cmd = ["tail", "-n", "1", "/etc/adjtime"]
                return __salt__["cmd.run"](cmd, python_shell=False)
        if "Debian" in __grains__["os_family"]:
            # Original way to look up hwclock on Debian-based systems
            try:
                with salt.utils.fopen("/etc/default/rcS", "r") as fp_:
                    for line in fp_:
                        if re.match(r"^\s*#", line):
                            continue
                        if "UTC=" in line:
                            is_utc = line.rstrip("\n").split("=")[-1].lower()
                            if is_utc == "yes":
                                return "UTC"
                            else:
                                return "localtime"
            except IOError as exc:
                pass
            # Since Wheezy
            cmd = ["tail", "-n", "1", "/etc/adjtime"]
            return __salt__["cmd.run"](cmd, python_shell=False)
        elif "Gentoo" in __grains__["os_family"]:
            offset_file = "/etc/conf.d/hwclock"
            try:
                with salt.utils.fopen(offset_file, "r") as fp_:
                    for line in fp_:
                        if line.startswith("clock="):
                            line = line.rstrip("\n")
                            return line.split("=")[-1].strip("'\"")
                    raise CommandExecutionError(
                        "Offset information not found in {0}".format(offset_file)
                    )
            except IOError as exc:
                raise CommandExecutionError(
                    "Problem reading offset file {0}: {1}".format(
                        offset_file, exc.strerror
                    )
                )
        elif "Solaris" in __grains__["os_family"]:
            offset_file = "/etc/rtc_config"
            try:
                with salt.utils.fopen(offset_file, "r") as fp_:
                    for line in fp_:
                        if line.startswith("zone_info=GMT"):
                            return "UTC"
                    return "localtime"
            except IOError as exc:
                if exc.errno == errno.ENOENT:
                    # offset file does not exist
                    return "UTC"
                raise CommandExecutionError(
                    "Problem reading offset file {0}: {1}".format(
                        offset_file, exc.strerror
                    )
                )


# Traceback (CommandExecutionError)
salt-call state.sls base.timezone -l debug
[DEBUG   ] Reading configuration from /etc/salt/minion
[DEBUG   ] Including configuration from '/etc/salt/minion.d/_schedule.conf'
[DEBUG   ] Reading configuration from /etc/salt/minion.d/_schedule.conf
[DEBUG   ] Including configuration from '/etc/salt/minion.d/grains.conf'
[DEBUG   ] Reading configuration from /etc/salt/minion.d/grains.conf
[DEBUG   ] Configuration file path: /etc/salt/minion
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Reading configuration from /etc/salt/minion
[DEBUG   ] Including configuration from '/etc/salt/minion.d/_schedule.conf'
[DEBUG   ] Reading configuration from /etc/salt/minion.d/_schedule.conf
[DEBUG   ] Including configuration from '/etc/salt/minion.d/grains.conf'
[DEBUG   ] Reading configuration from /etc/salt/minion.d/grains.conf
[DEBUG   ] Please install 'virt-what' to improve results of the 'virtual' grain.
[DEBUG   ] Initializing new SAuth for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506')
[DEBUG   ] Generated random reconnect delay between '1000ms' and '11000ms' (5858)
[DEBUG   ] Setting zmq_reconnect_ivl to '5858ms'
[DEBUG   ] Setting zmq_reconnect_ivl_max to '11000ms'
[DEBUG   ] Initializing new AsyncZeroMQReqChannel for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506', 'aes')
[DEBUG   ] Initializing new SAuth for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506')
[DEBUG   ] Initializing new AsyncZeroMQReqChannel for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506', 'clear')
[DEBUG   ] Decrypting the current master AES key
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] LazyLoaded state.sls
[DEBUG   ] LazyLoaded saltutil.is_running
[DEBUG   ] LazyLoaded grains.get
[DEBUG   ] Initializing new AsyncZeroMQReqChannel for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506', 'aes')
[DEBUG   ] Initializing new SAuth for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506')
[DEBUG   ] Initializing new AsyncZeroMQReqChannel for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506', 'aes')
[DEBUG   ] Initializing new SAuth for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506')
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[INFO    ] Loading fresh modules for state activity
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] In saltenv 'base', looking at rel_path u'base/timezone.sls' to resolve u'salt://base/timezone.sls'
[DEBUG   ] In saltenv 'base', ** considering ** path u'/var/cache/salt/minion/files/base/base/timezone.sls' to resolve u'salt://base/timezone.sls'
[DEBUG   ] Fetching file from saltenv 'base', ** attempting ** u'salt://base/timezone.sls'
[DEBUG   ] No dest file found
[INFO    ] Fetching file from saltenv 'base', ** done ** u'base/timezone.sls'
[DEBUG   ] compile template: /var/cache/salt/minion/files/base/base/timezone.sls
[DEBUG   ] Jinja search path: ['/var/cache/salt/minion/files/base']
[DEBUG   ] Rendered data from file: /var/cache/salt/minion/files/base/base/timezone.sls:
America/New_York:
timezone.system: []

[DEBUG   ] LazyLoaded config.get
[DEBUG   ] Results of YAML rendering:
OrderedDict([('America/New_York', OrderedDict([('timezone.system', [])]))])
[DEBUG   ] LazyLoaded timezone.get_zone
[DEBUG   ] LazyLoaded timezone.system
[INFO    ] Running state [America/New_York] at time 11:08:53.983795
[INFO    ] Executing state timezone.system for America/New_York
[DEBUG   ] LazyLoaded cmd.run
[INFO    ] Executing command ['timedatectl'] in directory '/root'
[ERROR   ] Command ['timedatectl'] failed with return code: 1
[ERROR   ] output: Failed to create bus connection: No such file or directory
[ERROR   ] An exception occurred in this state: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1591, in call
**cdata['kwargs'])
File "/usr/lib/python2.7/dist-packages/salt/states/timezone.py", line 73, in system
if __salt__['timezone.get_hwclock']() == 'localtime':
File "/usr/lib/python2.7/dist-packages/salt/modules/timezone.py", line 273, in get_hwclock
'Failed to parse timedatectl output, this is likely a bug'
CommandExecutionError: Failed to parse timedatectl output, this is likely a bug

[INFO    ] Completed state [America/New_York] at time 11:08:54.008322
[DEBUG   ] File /var/cache/salt/minion/accumulator/139778536598416 does not exist, no need to cleanup.
[DEBUG   ] LazyLoaded config.option
[DEBUG   ] Initializing new AsyncZeroMQReqChannel for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506', 'aes')
[DEBUG   ] Initializing new SAuth for ('/etc/salt/pki/minion', 'lnprmultidb02', 'tcp://10.10.15.189:4506')
[DEBUG   ] LazyLoaded highstate.output
local:
----------
ID: America/New_York
Function: timezone.system
Result: False
Comment: An exception occurred in this state: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1591, in call
**cdata['kwargs'])
File "/usr/lib/python2.7/dist-packages/salt/states/timezone.py", line 73, in system
if __salt__['timezone.get_hwclock']() == 'localtime':
File "/usr/lib/python2.7/dist-packages/salt/modules/timezone.py", line 273, in get_hwclock
'Failed to parse timedatectl output, this is likely a bug'
CommandExecutionError: Failed to parse timedatectl output, this is likely a bug
Started: 11:08:53.983795
Duration: 24.527 ms
Changes:

Summary for local
------------
Succeeded: 0
Failed:    1
------------
Total states run:     1
Total run time:  24.527 ms

# Fixed code
def get_hwclock():
    """
    Get current hardware clock setting (UTC or localtime)

    CLI Example:

    .. code-block:: bash

        salt '*' timezone.get_hwclock
    """
    cmd = ""
    if salt.utils.which("timedatectl"):
        ret = _timedatectl()
        for line in (x.strip() for x in ret["stdout"].splitlines()):
            if "rtc in local tz" in line.lower():
                try:
                    if line.split(":")[-1].strip().lower() == "yes":
                        return "localtime"
                    else:
                        return "UTC"
                except IndexError:
                    pass

        msg = (
            "Failed to parse timedatectl output: {0}\n"
            "Please file an issue with SaltStack"
        ).format(ret["stdout"])
        raise CommandExecutionError(msg)

    else:
        os_family = __grains__["os_family"]
        for family in ("RedHat", "Suse"):
            if family in os_family:
                cmd = ["tail", "-n", "1", "/etc/adjtime"]
                return __salt__["cmd.run"](cmd, python_shell=False)
        if "Debian" in __grains__["os_family"]:
            # Original way to look up hwclock on Debian-based systems
            try:
                with salt.utils.fopen("/etc/default/rcS", "r") as fp_:
                    for line in fp_:
                        if re.match(r"^\s*#", line):
                            continue
                        if "UTC=" in line:
                            is_utc = line.rstrip("\n").split("=")[-1].lower()
                            if is_utc == "yes":
                                return "UTC"
                            else:
                                return "localtime"
            except IOError as exc:
                pass
            # Since Wheezy
            cmd = ["tail", "-n", "1", "/etc/adjtime"]
            return __salt__["cmd.run"](cmd, python_shell=False)
        elif "Gentoo" in __grains__["os_family"]:
            offset_file = "/etc/conf.d/hwclock"
            try:
                with salt.utils.fopen(offset_file, "r") as fp_:
                    for line in fp_:
                        if line.startswith("clock="):
                            line = line.rstrip("\n")
                            return line.split("=")[-1].strip("'\"")
                    raise CommandExecutionError(
                        "Offset information not found in {0}".format(offset_file)
                    )
            except IOError as exc:
                raise CommandExecutionError(
                    "Problem reading offset file {0}: {1}".format(
                        offset_file, exc.strerror
                    )
                )
        elif "Solaris" in __grains__["os_family"]:
            offset_file = "/etc/rtc_config"
            try:
                with salt.utils.fopen(offset_file, "r") as fp_:
                    for line in fp_:
                        if line.startswith("zone_info=GMT"):
                            return "UTC"
                    return "localtime"
            except IOError as exc:
                if exc.errno == errno.ENOENT:
                    # offset file does not exist
                    return "UTC"
                raise CommandExecutionError(
                    "Problem reading offset file {0}: {1}".format(
                        offset_file, exc.strerror
                    )
                )