diff --git a/jc/cli.py b/jc/cli.py index d0ecc25c..ccf5877c 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -30,6 +30,9 @@ import jc.parsers.route import jc.parsers.ss import jc.parsers.stat import jc.parsers.systemctl +# import jc.parsers.systemctl_lj +# import jc.parsers.systemctl_lm +import jc.parsers.systemctl_ls import jc.parsers.systemctl_luf import jc.parsers.uname import jc.parsers.uptime @@ -69,7 +72,10 @@ def helptext(message): --ss ss parser --stat stat parser --systemctl systemctl parser - --systemctl-luf systemctl parser + --systemctl-lj systemctl list-jobs parser + --systemctl-lm systemctl list-machines parser + --systemctl-ls systemctl list-sockets parser + --systemctl-luf systemctl list-unit-files parser --uname uname -a parser --uptime uptime parser --w w parser @@ -136,6 +142,9 @@ def main(): '--ss': jc.parsers.ss.parse, '--stat': jc.parsers.stat.parse, '--systemctl': jc.parsers.systemctl.parse, + # '--systemctl-lj': jc.parsers.systemctl_lj.parse, + # '--systemctl-lm': jc.parsers.systemctl_lm.parse, + '--systemctl-ls': jc.parsers.systemctl_ls.parse, '--systemctl-luf': jc.parsers.systemctl_luf.parse, '--uname': jc.parsers.uname.parse, '--uptime': jc.parsers.uptime.parse, diff --git a/jc/parsers/systemctl.py b/jc/parsers/systemctl.py index e3f91c9c..7a589fc8 100644 --- a/jc/parsers/systemctl.py +++ b/jc/parsers/systemctl.py @@ -99,7 +99,7 @@ def parse(data, raw=False, quiet=False): break else: - entry_list = entry.split(maxsplit=4) + entry_list = entry.rstrip().split(maxsplit=4) output_line = dict(zip(header_list, entry_list)) raw_output.append(output_line) diff --git a/jc/parsers/systemctl_lj.py b/jc/parsers/systemctl_lj.py new file mode 100644 index 00000000..9840a9df --- /dev/null +++ b/jc/parsers/systemctl_lj.py @@ -0,0 +1,110 @@ +"""jc - JSON CLI output utility systemctl-luf Parser + +Usage: + specify --systemctl-luf as the first argument if the piped input is coming from systemctl --list-unit-files + +Examples: + + $ systemctl -a | jc --systemctl -p + [ + { + "unit": "proc-sys-fs-binfmt_misc.automount", + "load": "loaded", + "active": "active", + "sub": "waiting", + "description": "Arbitrary Executable File Formats File System Automount Point" + }, + { + "unit": "dev-block-8:2.device", + "load": "loaded", + "active": "active", + "sub": "plugged", + "description": "LVM PV 3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM on /dev/sda2 2" + }, + { + "unit": "dev-cdrom.device", + "load": "loaded", + "active": "active", + "sub": "plugged", + "description": "VMware_Virtual_IDE_CDROM_Drive" + }, + ... + ] +""" +import jc.utils + + +def process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (dictionary) raw structured data to process + + Returns: + + dictionary structured data with the following schema: + + [ + { + "unit": string, + "load": string, + "active": string, + "sub": string, + "description": string + } + ] + """ + # nothing more to process + return proc_data + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + dictionary raw or processed structured data + """ + + # compatible options: linux, darwin, cygwin, win32, aix, systemctlbsd + compatible = ['linux'] + + if not quiet: + jc.utils.compatibility(__name__, compatible) + + linedata = data.splitlines() + # Clear any blank lines + linedata = list(filter(None, linedata)) + # clean up non-ascii characters, if any + cleandata = [] + for entry in linedata: + cleandata.append(entry.encode('ascii', errors='ignore').decode()) + + header_text = cleandata[0] + header_text = header_text.lower().replace('unit file', 'unit_file') + header_list = header_text.split() + + raw_output = [] + + for entry in cleandata[1:]: + if entry.find('unit files listed.') != -1: + break + + else: + entry_list = entry.split(maxsplit=4) + output_line = dict(zip(header_list, entry_list)) + raw_output.append(output_line) + + if raw: + return raw_output + else: + return process(raw_output) diff --git a/jc/parsers/systemctl_lm.py b/jc/parsers/systemctl_lm.py new file mode 100644 index 00000000..9840a9df --- /dev/null +++ b/jc/parsers/systemctl_lm.py @@ -0,0 +1,110 @@ +"""jc - JSON CLI output utility systemctl-luf Parser + +Usage: + specify --systemctl-luf as the first argument if the piped input is coming from systemctl --list-unit-files + +Examples: + + $ systemctl -a | jc --systemctl -p + [ + { + "unit": "proc-sys-fs-binfmt_misc.automount", + "load": "loaded", + "active": "active", + "sub": "waiting", + "description": "Arbitrary Executable File Formats File System Automount Point" + }, + { + "unit": "dev-block-8:2.device", + "load": "loaded", + "active": "active", + "sub": "plugged", + "description": "LVM PV 3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM on /dev/sda2 2" + }, + { + "unit": "dev-cdrom.device", + "load": "loaded", + "active": "active", + "sub": "plugged", + "description": "VMware_Virtual_IDE_CDROM_Drive" + }, + ... + ] +""" +import jc.utils + + +def process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (dictionary) raw structured data to process + + Returns: + + dictionary structured data with the following schema: + + [ + { + "unit": string, + "load": string, + "active": string, + "sub": string, + "description": string + } + ] + """ + # nothing more to process + return proc_data + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + dictionary raw or processed structured data + """ + + # compatible options: linux, darwin, cygwin, win32, aix, systemctlbsd + compatible = ['linux'] + + if not quiet: + jc.utils.compatibility(__name__, compatible) + + linedata = data.splitlines() + # Clear any blank lines + linedata = list(filter(None, linedata)) + # clean up non-ascii characters, if any + cleandata = [] + for entry in linedata: + cleandata.append(entry.encode('ascii', errors='ignore').decode()) + + header_text = cleandata[0] + header_text = header_text.lower().replace('unit file', 'unit_file') + header_list = header_text.split() + + raw_output = [] + + for entry in cleandata[1:]: + if entry.find('unit files listed.') != -1: + break + + else: + entry_list = entry.split(maxsplit=4) + output_line = dict(zip(header_list, entry_list)) + raw_output.append(output_line) + + if raw: + return raw_output + else: + return process(raw_output) diff --git a/jc/parsers/systemctl_ls.py b/jc/parsers/systemctl_ls.py new file mode 100644 index 00000000..f8b7c717 --- /dev/null +++ b/jc/parsers/systemctl_ls.py @@ -0,0 +1,101 @@ +"""jc - JSON CLI output utility systemctl-ls Parser + +Usage: + specify --systemctl-luf as the first argument if the piped input is coming from systemctl list-sockets + +Examples: + + $ systemctl list-sockets | jc --systemctl-ls -p + [ + { + "listen": "/dev/log", + "unit": "systemd-journald.socket", + "activates": "systemd-journald.service" + }, + { + "listen": "/run/dbus/system_bus_socket", + "unit": "dbus.socket", + "activates": "dbus.service" + }, + { + "listen": "/run/dmeventd-client", + "unit": "dm-event.socket", + "activates": "dm-event.service" + }, + ... + ] +""" +import jc.utils + + +def process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (dictionary) raw structured data to process + + Returns: + + dictionary structured data with the following schema: + + [ + { + "listen": string, + "unit": string, + "activates": string + } + ] + """ + # nothing more to process + return proc_data + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + dictionary raw or processed structured data + """ + + # compatible options: linux, darwin, cygwin, win32, aix, systemctlbsd + compatible = ['linux'] + + if not quiet: + jc.utils.compatibility(__name__, compatible) + + linedata = data.splitlines() + # Clear any blank lines + linedata = list(filter(None, linedata)) + # clean up non-ascii characters, if any + cleandata = [] + for entry in linedata: + cleandata.append(entry.encode('ascii', errors='ignore').decode()) + + header_text = cleandata[0].lower() + header_list = header_text.split() + + raw_output = [] + + for entry in cleandata[1:]: + if entry.find('sockets listed.') != -1: + break + + else: + entry_list = entry.rsplit(maxsplit=2) + output_line = dict(zip(header_list, entry_list)) + raw_output.append(output_line) + + if raw: + return raw_output + else: + return process(raw_output) diff --git a/jc/parsers/systemctl_luf.py b/jc/parsers/systemctl_luf.py index 9840a9df..9b8e4aff 100644 --- a/jc/parsers/systemctl_luf.py +++ b/jc/parsers/systemctl_luf.py @@ -1,32 +1,23 @@ """jc - JSON CLI output utility systemctl-luf Parser Usage: - specify --systemctl-luf as the first argument if the piped input is coming from systemctl --list-unit-files + specify --systemctl-luf as the first argument if the piped input is coming from systemctl list-unit-files Examples: - $ systemctl -a | jc --systemctl -p + $ systemctl list-unit-files | jc --systemctl-luf -p [ { - "unit": "proc-sys-fs-binfmt_misc.automount", - "load": "loaded", - "active": "active", - "sub": "waiting", - "description": "Arbitrary Executable File Formats File System Automount Point" + "unit_file": "proc-sys-fs-binfmt_misc.automount", + "state": "static" }, { - "unit": "dev-block-8:2.device", - "load": "loaded", - "active": "active", - "sub": "plugged", - "description": "LVM PV 3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM on /dev/sda2 2" + "unit_file": "dev-hugepages.mount", + "state": "static" }, { - "unit": "dev-cdrom.device", - "load": "loaded", - "active": "active", - "sub": "plugged", - "description": "VMware_Virtual_IDE_CDROM_Drive" + "unit_file": "dev-mqueue.mount", + "state": "static" }, ... ] @@ -48,11 +39,8 @@ def process(proc_data): [ { - "unit": string, - "load": string, - "active": string, - "sub": string, - "description": string + "unit_file": string, + "state": string } ] """