From 03630c7e1ae968a7414a046f597e8c215b3b1aae Mon Sep 17 00:00:00 2001 From: Billy Holmes Date: Fri, 14 Sep 2018 05:21:50 +0000 Subject: [PATCH 1/6] added socket client code, added warnings output 1. removed references to netcat executable 2. implemented stats callback code as python sockets 3. added some exceptions to warning log 4. if warnings enabled, print out the warning log of caught exceptions --- motd_gen.py | 62 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/motd_gen.py b/motd_gen.py index 2f0139e..955b70f 100755 --- a/motd_gen.py +++ b/motd_gen.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# vim: ts=4 sw=4 ai expandtab # Written in 2012 by Joe Tsai # @@ -27,6 +28,9 @@ import getpass import optparse import datetime +import socket +from StringIO import StringIO as SIO +import traceback ################################################################################ @@ -91,6 +95,7 @@ CACHE_FREE = True # Is disk cache considered free memory or not? FULL_HOSTNAME = False # Use the full FQDN hostname STAT_PORT = 4004 # Port for the motd_netstat daemon +STAT_HOST = 'localhost' # Host for the motd_netstat daemon NETTRAF_DEVICE = 'eth0' # The network device to monitor NETTRAF_INTERVAL = 600 # Time length in seconds to average the bandwidth over NETTRAF_WEIGHT = 1.0 # Perform linear moving average weight @@ -107,6 +112,34 @@ ############################### Helper functions ############################### ################################################################################ +def send_to_port(host, port, payload): + for res in socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + received = SIO() + s = socket.socket(af, socktype, proto) + try: + s.connect(sa) + s.send(payload) + for tmp in s.recv(1024): + received.write(tmp) + return received.getvalue() + finally: + s.close() + received.close() + +def extract_error(): + """Extracts meaning error from a caught exception""" + info = sys.exc_info() + tb = traceback.extract_tb(info[2])[0] + _file = tb[0] + _line = tb[1] + return "%s(%s) at %s line %s" % ( + colorize('exception',CYAN0), + colorize(str(info[1]), YELLOW0), + colorize(_file, YELLOW1), + colorize(_line, YELLOW1) + ) + def exec_cmd(cmd): """Execute a command and retrieve standard output""" with os.popen(cmd + ' 2> /dev/null', 'r') as cmd_call: @@ -239,6 +272,14 @@ def display_info(): key = (key + ':').ljust(max_length + 4, ' ') print " %s%s" % (colorize(key, TEXT_SECONDARY), value) +def display_warnings(): + """Display any warnings from the WARN_LOG""" + global WARN_LOG + global opts + if not opts.warn: + return + for warning in WARN_LOG: + print " - %s %s" % (colorize('WARNING:', WARNING), colorize(warning, RESET)) ################################################################################ ################################ Options parser ################################ @@ -325,6 +366,8 @@ def display_info(): # Generate info list result_list = [] +WARN_LOG = [] + # Get last login try: login_host = exec_cmd('last -n 2 -w -F $USER') @@ -429,9 +472,8 @@ def display_info(): 'weight': CPUUTIL_WEIGHT, } } - query = shell_escape(json.dumps(query)) - command = 'echo %s | netcat localhost %s' % (query,STAT_PORT) - util_usage = ''.join(exec_cmd(command)).strip() + query = json.dumps(query) + util_usage = send_to_port(STAT_HOST, STAT_PORT, query).strip() # Load the JSON data data = json.loads(util_usage) @@ -446,8 +488,8 @@ def display_info(): values = tuple(utils_text) message = "%s (1 minute) - %s (5 minutes) - %s (15 minutes)" % values info_list.append(('CPU utilization', message)) -except: - pass +except Exception as ex: + WARN_LOG.append(extract_error()) # Get CPU load try: @@ -519,9 +561,8 @@ def display_info(): 'weight': NETTRAF_WEIGHT, } } - query = shell_escape(json.dumps(query)) - command = 'echo %s | netcat localhost %s' % (query, STAT_PORT) - net_usage = ''.join(exec_cmd(command)).strip() + query = json.dumps(query) + net_usage = send_to_port(STAT_HOST, STAT_PORT, query).strip() # Load the JSON data data = json.loads(net_usage) @@ -534,8 +575,8 @@ def display_info(): values = total_text,units(rx_avg, 'B/s'), units(tx_avg, 'B/s') message = "%s - %s down, %s up" % values info_list.append(('Network traffic', message)) -except: - pass +except Exception as ex: + WARN_LOG.append(extract_error()) # Get processes try: @@ -555,4 +596,5 @@ def display_info(): display_welcome() display_logo() display_info() +display_warnings() display_lower_border() From 8746dbc78af0c11a06882fb466b5a1351fdfe89f Mon Sep 17 00:00:00 2001 From: Billy Holmes Date: Fri, 14 Sep 2018 06:08:50 +0000 Subject: [PATCH 2/6] added addtional logic for welcome message `/etc/issue` isn't a good way to obtain release information as [outlined in this blog][1]. Therefore, I'm reading it from `/etc/os-release` which appears to be in: * CentOs * Fedora * RHEL * Ubuntu If that fails, then it continues to read from `/etc/issue` [1]: https://gerardnico.com/linux/version --- motd_gen.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/motd_gen.py b/motd_gen.py index 955b70f..6eee1c7 100755 --- a/motd_gen.py +++ b/motd_gen.py @@ -247,11 +247,22 @@ def display_lower_border(): """Display the lower border""" display_border(LOWER_HALF_BLOCK) +def _strip_list(l): + return map(lambda x: x.strip('\r\n\t "'), l) def display_welcome(): """Display the welcome message""" - os_issue = ''.join(read_file('/etc/issue')).strip() - os_name = re.sub(r'\\[a-zA-Z]', '', os_issue).strip() + os_release = None + os_name = None + try: + _filter = filter(lambda x: x, _strip_list(read_file('/etc/os-release') ) ) + os_release = dict(map( lambda x: _strip_list(x.split('=') ), _filter) ) + os_name = "%s %s" % (os_release['NAME'], colorize(os_release['VERSION'], GREEN1)) + except: + pass + if not os_release: + os_issue = ''.join(read_file('/etc/issue')).strip() + os_name = re.sub(r'\\[a-zA-Z]', '', os_issue).strip() cmd = 'hostname -f' if FULL_HOSTNAME else 'hostname' host_name = ''.join(exec_cmd(cmd)).strip() values = colorize(host_name, TEXT_PRIMARY), colorize(os_name, TEXT_PRIMARY) From f2f38e73bd57f75ddefc05c2a8339b6e5a68b7a2 Mon Sep 17 00:00:00 2001 From: Billy Holmes Date: Fri, 14 Sep 2018 06:20:27 +0000 Subject: [PATCH 3/6] added motd-gen.spec and motd_stat.service --- motd-gen.spec | 40 ++++++++++++++++++++++++++++++++++++++++ motd_stat.service | 16 ++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 motd-gen.spec create mode 100644 motd_stat.service diff --git a/motd-gen.spec b/motd-gen.spec new file mode 100644 index 0000000..c338c85 --- /dev/null +++ b/motd-gen.spec @@ -0,0 +1,40 @@ +Name: MOTD Generator +Version: 1.0.0 +Release: 1%{?dist} +Summary: Custom message of the day (MOTD) designed to be as practical and informative as possible. + +License: Unknown +URL: https://github.com/gonoph/motd-generator +Source0: https://github.com/gonoph/motd-generator/archive/motd-generator-1.0.0.tar.gz + +Requires: systemd + +%description +This is a custom message of the day (MOTD) designed to be as practical and +informative as possible. The truth is, no one actually reads the MOTD. As such, +the MOTD should contain useful, yet minimal, information about the host system +such that a quick glance at it when logging in may actually be worth a person's +precious time. This way, any potential issues are noticed and not naively +ignored. This MOTD generator scripts has the ability to output text in color. +Using this feature, potential issues can be highlighted for easy +identification. + + +%prep +%setup -q + + +%build + + +%install +make install DESTDIR=%{buildroot} + + +%files +%doc + + + +%changelog + diff --git a/motd_stat.service b/motd_stat.service new file mode 100644 index 0000000..b06075a --- /dev/null +++ b/motd_stat.service @@ -0,0 +1,16 @@ +[Unit] +Description=dsnet motd stat service +After=sshd.service +After=getty.target + +[Service] +Type=simple +Restart=always +RestartSec=5 +User=centos +WorkingDirectory=/var/lib/motd_gen +User=motd_gen +ExecStart=/usr/bin/motd_stat.py + +[Install] +WantedBy=multi-user.target From f8bfe2824ed20a58a8f4ac6e8c40e35ffb603319 Mon Sep 17 00:00:00 2001 From: Billy Holmes Date: Fri, 14 Sep 2018 07:25:16 +0000 Subject: [PATCH 4/6] Updated spec and services file --- motd-gen.spec | 40 ------------------------ motd-generator.spec | 74 +++++++++++++++++++++++++++++++++++++++++++++ motd_stat.service | 6 ++-- 3 files changed, 78 insertions(+), 42 deletions(-) delete mode 100644 motd-gen.spec create mode 100644 motd-generator.spec diff --git a/motd-gen.spec b/motd-gen.spec deleted file mode 100644 index c338c85..0000000 --- a/motd-gen.spec +++ /dev/null @@ -1,40 +0,0 @@ -Name: MOTD Generator -Version: 1.0.0 -Release: 1%{?dist} -Summary: Custom message of the day (MOTD) designed to be as practical and informative as possible. - -License: Unknown -URL: https://github.com/gonoph/motd-generator -Source0: https://github.com/gonoph/motd-generator/archive/motd-generator-1.0.0.tar.gz - -Requires: systemd - -%description -This is a custom message of the day (MOTD) designed to be as practical and -informative as possible. The truth is, no one actually reads the MOTD. As such, -the MOTD should contain useful, yet minimal, information about the host system -such that a quick glance at it when logging in may actually be worth a person's -precious time. This way, any potential issues are noticed and not naively -ignored. This MOTD generator scripts has the ability to output text in color. -Using this feature, potential issues can be highlighted for easy -identification. - - -%prep -%setup -q - - -%build - - -%install -make install DESTDIR=%{buildroot} - - -%files -%doc - - - -%changelog - diff --git a/motd-generator.spec b/motd-generator.spec new file mode 100644 index 0000000..bbda5bf --- /dev/null +++ b/motd-generator.spec @@ -0,0 +1,74 @@ +Name: motd-generator +Version: 1.0.0 +Release: 1%{?dist} +Summary: Custom message of the day (MOTD) designed to be as practical and informative as possible. + +License: Unknown +URL: https://github.com/gonoph/motd-generator +Source0: https://github.com/gonoph/motd-generator/archive/v1.0.0.tar.gz + +Requires: systemd + +%{?systemd_requires} + +%description +This is a custom message of the day (MOTD) designed to be as practical and +informative as possible. The truth is, no one actually reads the MOTD. As such, +the MOTD should contain useful, yet minimal, information about the host system +such that a quick glance at it when logging in may actually be worth a person's +precious time. This way, any potential issues are noticed and not naively +ignored. This MOTD generator scripts has the ability to output text in color. +Using this feature, potential issues can be highlighted for easy +identification. + + +%prep +%setup -q + +# %build + + +%install +DESTDIR=%{buildroot} +DIR_BIN=${DESTDIR}%{_bindir} +DIR_STATE=${DESTDIR}%{_sharedstatedir}/%{name} +DIR_SYSTEMD=${DESTDIR}%{_exec_prefix}/lib/systemd/system +DIR_PRESETS=${DESTDIR}%{_exec_prefix}/lib/systemd/system-preset/ +mkdir -p $DIR_BIN +mkdir -p $DIR_STATE +mkdir -p $DIR_SYSTEMD +install -m 755 -t $DIR_BIN motd_gen.py motd_stat.py +install -m 644 -t $DIR_SYSTEMD motd_stat.service +echo "enable motd_stat.service" > $DIR_PRESETS/50-motd_stat.preset + +%pre +U=$(getent passwd motd) +test "x$U" == "x" && useradd -r -d $DIR_STATE -M -U motd || : + +%post +%systemd_post motd_stat.service + +%preun +%systemd_preun motd_stat.service + +%postun +%systemd_postun_with_restart motd_stat.service +if [ $1 -gt 0 ] ; then + exit 0 +fi +userdel motd || : + +%files +%defattr(644, motd, motd, -) +%attr(755,-,-) %{_bindir}/motd_gen.py +%attr(755,-,-) %{_bindir}/motd_stat.py +%{_sharedstatedir}/%{name} +%{_exec_prefix}/lib/systemd/system/motd_stat.service +%{_exec_prefix}/lib/systemd/system-preset/50-motd_stat.preset +%doc README.md +%doc motd_stat +%dir %{_sharedstatedir}/%{name} + +%changelog +* Fri Sep 14 2018 Billy Holmes - 1.0.0-1 +- Initial release diff --git a/motd_stat.service b/motd_stat.service index b06075a..e72f72e 100644 --- a/motd_stat.service +++ b/motd_stat.service @@ -7,10 +7,12 @@ After=getty.target Type=simple Restart=always RestartSec=5 -User=centos WorkingDirectory=/var/lib/motd_gen -User=motd_gen +User=motd +Group=motd ExecStart=/usr/bin/motd_stat.py +MemoryHigh=100M +CPUQuota=20% [Install] WantedBy=multi-user.target From e6c24732b975dc11b3dff51377bc9ac4c3ecb621 Mon Sep 17 00:00:00 2001 From: Billy Holmes Date: Fri, 14 Sep 2018 07:58:25 +0000 Subject: [PATCH 5/6] resolved some bugs in the the startup and service file * Was missing the profile.d in the build. * changed the MemoryHigh to MemoryLimit as systemd doesn't understand it on RHEL 7.5 --- motd-generator.spec | 20 ++++++++++++++++++-- motd_stat.service | 4 ++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/motd-generator.spec b/motd-generator.spec index bbda5bf..405b2e3 100644 --- a/motd-generator.spec +++ b/motd-generator.spec @@ -2,6 +2,7 @@ Name: motd-generator Version: 1.0.0 Release: 1%{?dist} Summary: Custom message of the day (MOTD) designed to be as practical and informative as possible. +BuildArch: noarch License: Unknown URL: https://github.com/gonoph/motd-generator @@ -10,6 +11,7 @@ Source0: https://github.com/gonoph/motd-generator/archive/v1.0.0.tar.gz Requires: systemd %{?systemd_requires} +BuildRequires: systemd %description This is a custom message of the day (MOTD) designed to be as practical and @@ -34,16 +36,29 @@ DIR_BIN=${DESTDIR}%{_bindir} DIR_STATE=${DESTDIR}%{_sharedstatedir}/%{name} DIR_SYSTEMD=${DESTDIR}%{_exec_prefix}/lib/systemd/system DIR_PRESETS=${DESTDIR}%{_exec_prefix}/lib/systemd/system-preset/ +DIR_PROFILE=${DESTDIR}%{_sysconfdir}/profile.d mkdir -p $DIR_BIN mkdir -p $DIR_STATE mkdir -p $DIR_SYSTEMD +mkdir -p $DIR_PRESETS +mkdir -p $DIR_PROFILE install -m 755 -t $DIR_BIN motd_gen.py motd_stat.py install -m 644 -t $DIR_SYSTEMD motd_stat.service echo "enable motd_stat.service" > $DIR_PRESETS/50-motd_stat.preset +cat << EOF > $DIR_PROFILE/motd_gen.sh +if [ -e %{_bindir}/motd_gen.py ]; then + if [ -x %{_bindir}/dircolors ]; then + %{_bindir}/motd_gen.py --color --warn --border + else + %{_bindir}/motd_gen.py --border + fi +fi +EOF %pre +DIR_STATE=${DESTDIR}%{_sharedstatedir}/%{name} U=$(getent passwd motd) -test "x$U" == "x" && useradd -r -d $DIR_STATE -M -U motd || : +test "x$U" == x && useradd -r -d $DIR_STATE -M -U motd || : %post %systemd_post motd_stat.service @@ -59,12 +74,13 @@ fi userdel motd || : %files -%defattr(644, motd, motd, -) +%defattr(644, motd, motd, 755) %attr(755,-,-) %{_bindir}/motd_gen.py %attr(755,-,-) %{_bindir}/motd_stat.py %{_sharedstatedir}/%{name} %{_exec_prefix}/lib/systemd/system/motd_stat.service %{_exec_prefix}/lib/systemd/system-preset/50-motd_stat.preset +%{_sysconfdir}/profile.d/motd_gen.sh %doc README.md %doc motd_stat %dir %{_sharedstatedir}/%{name} diff --git a/motd_stat.service b/motd_stat.service index e72f72e..e3a930d 100644 --- a/motd_stat.service +++ b/motd_stat.service @@ -7,11 +7,11 @@ After=getty.target Type=simple Restart=always RestartSec=5 -WorkingDirectory=/var/lib/motd_gen +WorkingDirectory=/var/lib/motd-generator User=motd Group=motd ExecStart=/usr/bin/motd_stat.py -MemoryHigh=100M +MemoryLimit=128M CPUQuota=20% [Install] From 3602664919839172a0e296c8f3bc0c0cf6182da7 Mon Sep 17 00:00:00 2001 From: Billy Holmes Date: Fri, 14 Sep 2018 21:06:09 +0000 Subject: [PATCH 6/6] clean up spec file trying to get automated builds working --- motd-generator.spec | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/motd-generator.spec b/motd-generator.spec index 405b2e3..286f655 100644 --- a/motd-generator.spec +++ b/motd-generator.spec @@ -1,17 +1,23 @@ Name: motd-generator -Version: 1.0.0 -Release: 1%{?dist} +Version: 1.0.1 +%define build_timestamp %{lua: print(os.date("%Y%m%d"))} +Release: %{build_timestamp} Summary: Custom message of the day (MOTD) designed to be as practical and informative as possible. BuildArch: noarch License: Unknown URL: https://github.com/gonoph/motd-generator -Source0: https://github.com/gonoph/motd-generator/archive/v1.0.0.tar.gz +Source0: https://github.com/gonoph/motd-generator/archive/systemd.tar.gz Requires: systemd +Requires: python +Requires: python(abi) = 2.7 + +Provides: motd %{?systemd_requires} BuildRequires: systemd +Buildrequires: python %description This is a custom message of the day (MOTD) designed to be as practical and @@ -25,7 +31,7 @@ identification. %prep -%setup -q +%autosetup -n %{name}-systemd # %build