From b17c8d481c86a1f94e8294c5b2006019d3faa707 Mon Sep 17 00:00:00 2001 From: telyn Date: Mon, 8 May 2017 18:58:45 +0100 Subject: [PATCH 01/17] Run symbiosis-monit from a systemd timer. --- monit/debian/control | 2 +- monit/debian/rules | 2 +- monit/debian/symbiosis-monit.service | 6 ++++++ monit/debian/symbiosis-monit.timer | 9 +++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 monit/debian/symbiosis-monit.service create mode 100644 monit/debian/symbiosis-monit.timer diff --git a/monit/debian/control b/monit/debian/control index 024f6b1d..1a1b869e 100644 --- a/monit/debian/control +++ b/monit/debian/control @@ -3,7 +3,7 @@ Section: web Priority: extra Maintainer: James Carter Uploaders: Patrick J Cherry , Steve Kemp -Build-Depends: debhelper (>= 7.0.0), txt2man, gem2deb, ruby +Build-Depends: debhelper (>= 7.0.0), txt2man, gem2deb, ruby, dh-systemd Standards-Version: 3.9.6 XS-Ruby-Versions: all diff --git a/monit/debian/rules b/monit/debian/rules index df588234..a3bf5724 100755 --- a/monit/debian/rules +++ b/monit/debian/rules @@ -14,7 +14,7 @@ #export DH_RUBY_GEMSPEC=gem.gemspec %: - dh $@ --buildsystem=ruby --with ruby + dh $@ --buildsystem=ruby --with ruby,systemd override_dh_auto_build-indep: $(MAKE) all diff --git a/monit/debian/symbiosis-monit.service b/monit/debian/symbiosis-monit.service new file mode 100644 index 00000000..f3629723 --- /dev/null +++ b/monit/debian/symbiosis-monit.service @@ -0,0 +1,6 @@ +[Unit] +Description=Symbiosis monitoring + +[Service] +Type=oneshot +ExecStart=/usr/sbin/symbiosis-monit diff --git a/monit/debian/symbiosis-monit.timer b/monit/debian/symbiosis-monit.timer new file mode 100644 index 00000000..b854b686 --- /dev/null +++ b/monit/debian/symbiosis-monit.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Regularly execute symbiosis-monit.service + +[Timer] +# run every 2 minutes +OnCalendar=* *-*-* *:00,02,04,06,08,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58:00 + +[Install] +WantedBy=timers.target From 6cdb7c12785bbeaae65c0eda035ac650fb7ef4fc Mon Sep 17 00:00:00 2001 From: telyn Date: Tue, 9 May 2017 10:36:21 +0100 Subject: [PATCH 02/17] DIY the timer install --- monit/debian/postinst | 7 +++++++ monit/debian/symbiosis-monit.install | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/monit/debian/postinst b/monit/debian/postinst index 1d13d449..ba57b62a 100755 --- a/monit/debian/postinst +++ b/monit/debian/postinst @@ -46,4 +46,11 @@ fi mkdir -p /var/lib/symbiosis/ #DEBHELPER# + +if systemctl status >/dev/null 2>&1; then + echo "I: Enabling symbiosis-monit.timer" + systemctl enable symbiosis-monit.timer + systemctl start symbiosis-monit.timer +fi + exit 0 diff --git a/monit/debian/symbiosis-monit.install b/monit/debian/symbiosis-monit.install index 22045c64..786ac329 100644 --- a/monit/debian/symbiosis-monit.install +++ b/monit/debian/symbiosis-monit.install @@ -3,4 +3,4 @@ monit.d/* etc/symbiosis/monit.d/ templates/* usr/share/symbiosis/monit/ lib/* usr/lib/ruby/vendor_ruby/ test.d/* etc/symbiosis/test.d/ - +debian/symbiosis-monit.timer lib/systemd/system/ From 0632730ca4d37ec2e426c6d3d770ad0553f0850a Mon Sep 17 00:00:00 2001 From: telyn Date: Tue, 9 May 2017 11:47:44 +0100 Subject: [PATCH 03/17] Revert "DIY the timer install" This reverts commit 6cdb7c12785bbeaae65c0eda035ac650fb7ef4fc. --- monit/debian/postinst | 7 ------- monit/debian/symbiosis-monit.install | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/monit/debian/postinst b/monit/debian/postinst index ba57b62a..1d13d449 100755 --- a/monit/debian/postinst +++ b/monit/debian/postinst @@ -46,11 +46,4 @@ fi mkdir -p /var/lib/symbiosis/ #DEBHELPER# - -if systemctl status >/dev/null 2>&1; then - echo "I: Enabling symbiosis-monit.timer" - systemctl enable symbiosis-monit.timer - systemctl start symbiosis-monit.timer -fi - exit 0 diff --git a/monit/debian/symbiosis-monit.install b/monit/debian/symbiosis-monit.install index 786ac329..22045c64 100644 --- a/monit/debian/symbiosis-monit.install +++ b/monit/debian/symbiosis-monit.install @@ -3,4 +3,4 @@ monit.d/* etc/symbiosis/monit.d/ templates/* usr/share/symbiosis/monit/ lib/* usr/lib/ruby/vendor_ruby/ test.d/* etc/symbiosis/test.d/ -debian/symbiosis-monit.timer lib/systemd/system/ + From 8cea90a14973e5fb571a9249ef132108d4f817c2 Mon Sep 17 00:00:00 2001 From: telyn Date: Tue, 9 May 2017 11:53:32 +0100 Subject: [PATCH 04/17] add the timer to the debian install file --- monit/debian/symbiosis-monit.install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monit/debian/symbiosis-monit.install b/monit/debian/symbiosis-monit.install index 22045c64..786ac329 100644 --- a/monit/debian/symbiosis-monit.install +++ b/monit/debian/symbiosis-monit.install @@ -3,4 +3,4 @@ monit.d/* etc/symbiosis/monit.d/ templates/* usr/share/symbiosis/monit/ lib/* usr/lib/ruby/vendor_ruby/ test.d/* etc/symbiosis/test.d/ - +debian/symbiosis-monit.timer lib/systemd/system/ From c168a15af6f67b244afd84feb3e11914ae20f5e1 Mon Sep 17 00:00:00 2001 From: telyn Date: Tue, 9 May 2017 12:01:25 +0100 Subject: [PATCH 05/17] simplifiy OnCalendar spec --- monit/debian/symbiosis-monit.timer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monit/debian/symbiosis-monit.timer b/monit/debian/symbiosis-monit.timer index b854b686..5aeacb94 100644 --- a/monit/debian/symbiosis-monit.timer +++ b/monit/debian/symbiosis-monit.timer @@ -3,7 +3,7 @@ Description=Regularly execute symbiosis-monit.service [Timer] # run every 2 minutes -OnCalendar=* *-*-* *:00,02,04,06,08,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58:00 +OnCalendar=*:0/2 [Install] WantedBy=timers.target From 056c95b92d50f05a35256e5e7518168cb9a2f237 Mon Sep 17 00:00:00 2001 From: telyn Date: Tue, 9 May 2017 12:28:35 +0100 Subject: [PATCH 06/17] Switch type to simple --- monit/debian/symbiosis-monit.service | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/monit/debian/symbiosis-monit.service b/monit/debian/symbiosis-monit.service index f3629723..e5136fe0 100644 --- a/monit/debian/symbiosis-monit.service +++ b/monit/debian/symbiosis-monit.service @@ -1,6 +1,6 @@ [Unit] -Description=Symbiosis monitoring +Description=Symbiosis monitor [Service] -Type=oneshot -ExecStart=/usr/sbin/symbiosis-monit +Type=simple +ExecStart=/usr/sbin/symbiosis-monit -t email /etc/symbiosis/monit.d From 3b4a73619316c880fb14359c34267d6e8115b067 Mon Sep 17 00:00:00 2001 From: telyn Date: Wed, 10 May 2017 12:13:01 +0100 Subject: [PATCH 07/17] symbiosis-monit now emails on failure under systemd --- monit/debian/symbiosis-monit.install | 4 ++-- monit/debian/symbiosis-monit.service | 6 ------ monit/sbin/symbiosis-monit-failure-email | 8 ++++++++ monit/system/symbiosis-monit-failure-email.service | 6 ++++++ monit/system/symbiosis-monit.service | 8 ++++++++ 5 files changed, 24 insertions(+), 8 deletions(-) delete mode 100644 monit/debian/symbiosis-monit.service create mode 100644 monit/sbin/symbiosis-monit-failure-email create mode 100644 monit/system/symbiosis-monit-failure-email.service create mode 100644 monit/system/symbiosis-monit.service diff --git a/monit/debian/symbiosis-monit.install b/monit/debian/symbiosis-monit.install index 786ac329..94afbc85 100644 --- a/monit/debian/symbiosis-monit.install +++ b/monit/debian/symbiosis-monit.install @@ -1,6 +1,6 @@ -sbin/symbiosis-monit usr/sbin/ +sbin/* usr/sbin/ monit.d/* etc/symbiosis/monit.d/ templates/* usr/share/symbiosis/monit/ lib/* usr/lib/ruby/vendor_ruby/ test.d/* etc/symbiosis/test.d/ -debian/symbiosis-monit.timer lib/systemd/system/ +system/* lib/systemd/ diff --git a/monit/debian/symbiosis-monit.service b/monit/debian/symbiosis-monit.service deleted file mode 100644 index e5136fe0..00000000 --- a/monit/debian/symbiosis-monit.service +++ /dev/null @@ -1,6 +0,0 @@ -[Unit] -Description=Symbiosis monitor - -[Service] -Type=simple -ExecStart=/usr/sbin/symbiosis-monit -t email /etc/symbiosis/monit.d diff --git a/monit/sbin/symbiosis-monit-failure-email b/monit/sbin/symbiosis-monit-failure-email new file mode 100644 index 00000000..f4200ab1 --- /dev/null +++ b/monit/sbin/symbiosis-monit-failure-email @@ -0,0 +1,8 @@ +#!/bin/bash + +set -e + +args="--since=today" +[ -e "/run/symbiosis-monit.cursor" ] && args="--after-cursor=$( /run/symbiosis-monit.cursor' +ExecStart=/usr/sbin/symbiosis-monit -t email /etc/symbiosis/monit.d From 7075ea9282b21d869d5ca858b3bfba938b1396bf Mon Sep 17 00:00:00 2001 From: telyn Date: Wed, 10 May 2017 12:33:31 +0100 Subject: [PATCH 08/17] Fix systemd system dir in symbiosis-monit install spec --- monit/debian/symbiosis-monit.install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monit/debian/symbiosis-monit.install b/monit/debian/symbiosis-monit.install index 94afbc85..68f3c74b 100644 --- a/monit/debian/symbiosis-monit.install +++ b/monit/debian/symbiosis-monit.install @@ -3,4 +3,4 @@ monit.d/* etc/symbiosis/monit.d/ templates/* usr/share/symbiosis/monit/ lib/* usr/lib/ruby/vendor_ruby/ test.d/* etc/symbiosis/test.d/ -system/* lib/systemd/ +system/* lib/systemd/system/ From 225ad6be704375aa7551fc5a59fdf863ab21796b Mon Sep 17 00:00:00 2001 From: telyn Date: Wed, 10 May 2017 12:37:10 +0100 Subject: [PATCH 09/17] Move symbiosis-monit timer into system folder --- monit/{debian => system}/symbiosis-monit.timer | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename monit/{debian => system}/symbiosis-monit.timer (100%) diff --git a/monit/debian/symbiosis-monit.timer b/monit/system/symbiosis-monit.timer similarity index 100% rename from monit/debian/symbiosis-monit.timer rename to monit/system/symbiosis-monit.timer From d8b6ba8ecaa63bdafb4420fa3794f6cc9d3db319 Mon Sep 17 00:00:00 2001 From: telyn Date: Fri, 12 May 2017 15:53:04 +0100 Subject: [PATCH 10/17] Drop privileges when writing to symbiosis-monit.cursor --- monit/sbin/symbiosis-monit-failure-email | 2 +- monit/system/symbiosis-monit-failure-email.service | 2 +- monit/system/symbiosis-monit.service | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) mode change 100644 => 100755 monit/sbin/symbiosis-monit-failure-email diff --git a/monit/sbin/symbiosis-monit-failure-email b/monit/sbin/symbiosis-monit-failure-email old mode 100644 new mode 100755 index f4200ab1..1f68edb6 --- a/monit/sbin/symbiosis-monit-failure-email +++ b/monit/sbin/symbiosis-monit-failure-email @@ -3,6 +3,6 @@ set -e args="--since=today" -[ -e "/run/symbiosis-monit.cursor" ] && args="--after-cursor=$( /run/symbiosis-monit.cursor' -ExecStart=/usr/sbin/symbiosis-monit -t email /etc/symbiosis/monit.d +ExecStartPre=/bin/sh -c 'journalctl -o cat -n 0 -u %n --show-cursor | cut -f3 -d" " > /var/tmp/symbiosis-monit.cursor' +ExecStart=+/usr/sbin/symbiosis-monit -t email /etc/symbiosis/monit.d +User=nobody +Group=nobody From d92a22b9075f3b423d96e45d81a43458432e52d7 Mon Sep 17 00:00:00 2001 From: telyn Date: Fri, 12 May 2017 17:07:46 +0100 Subject: [PATCH 11/17] Fix mistake in symbiosis-monit-failure-email --- monit/sbin/symbiosis-monit-failure-email | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monit/sbin/symbiosis-monit-failure-email b/monit/sbin/symbiosis-monit-failure-email index 1f68edb6..6185dd36 100755 --- a/monit/sbin/symbiosis-monit-failure-email +++ b/monit/sbin/symbiosis-monit-failure-email @@ -3,6 +3,6 @@ set -e args="--since=today" -[ -e "/run/symbiosis-monit.cursor" ] && args="--after-cursor=$( Date: Fri, 12 May 2017 17:11:35 +0100 Subject: [PATCH 12/17] Fix cursor passing to journalctl in symbiosis-monit-failure-email --- monit/sbin/symbiosis-monit-failure-email | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monit/sbin/symbiosis-monit-failure-email b/monit/sbin/symbiosis-monit-failure-email index 6185dd36..17e12c64 100755 --- a/monit/sbin/symbiosis-monit-failure-email +++ b/monit/sbin/symbiosis-monit-failure-email @@ -3,6 +3,6 @@ set -e args="--since=today" -[ -e "/var/tmp/symbiosis-monit.cursor" ] && args="--after-cursor=$( Date: Fri, 12 May 2017 17:19:48 +0100 Subject: [PATCH 13/17] Revert "Fix cursor passing to journalctl in symbiosis-monit-failure-email" This reverts commit 0e69c93a74eefb76c909e33a02679a2bcb2146bc. --- monit/sbin/symbiosis-monit-failure-email | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monit/sbin/symbiosis-monit-failure-email b/monit/sbin/symbiosis-monit-failure-email index 17e12c64..6185dd36 100755 --- a/monit/sbin/symbiosis-monit-failure-email +++ b/monit/sbin/symbiosis-monit-failure-email @@ -3,6 +3,6 @@ set -e args="--since=today" -[ -e "/var/tmp/symbiosis-monit.cursor" ] && args="--after-cursor='$( Date: Fri, 12 May 2017 17:20:52 +0100 Subject: [PATCH 14/17] Fix symbiosis-monit failure email for good (i think) --- monit/system/symbiosis-monit.service | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/monit/system/symbiosis-monit.service b/monit/system/symbiosis-monit.service index 55635737..817186e0 100644 --- a/monit/system/symbiosis-monit.service +++ b/monit/system/symbiosis-monit.service @@ -4,7 +4,5 @@ OnFailure=symbiosis-monit-failure-email.service [Service] Type=simple -ExecStartPre=/bin/sh -c 'journalctl -o cat -n 0 -u %n --show-cursor | cut -f3 -d" " > /var/tmp/symbiosis-monit.cursor' -ExecStart=+/usr/sbin/symbiosis-monit -t email /etc/symbiosis/monit.d -User=nobody -Group=nobody +ExecStartPre=/bin/sh -c 'journalctl -o cat -n 0 -u %n --show-cursor | cut -f3 -d" " | sudo -u nobody tee /var/tmp/symbiosis-monit.cursor >/dev/null' +ExecStart=/usr/sbin/symbiosis-monit -t email /etc/symbiosis/monit.d From 14c601eb32f38d0cd9d656bead88871198797050 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 7 Jun 2017 16:00:58 +0100 Subject: [PATCH 15/17] Rubocop'd --- cron/lib/symbiosis/crontab.rb | 311 ++++++++++++++++------------------ 1 file changed, 148 insertions(+), 163 deletions(-) diff --git a/cron/lib/symbiosis/crontab.rb b/cron/lib/symbiosis/crontab.rb index dddae4f8..772a0d8b 100644 --- a/cron/lib/symbiosis/crontab.rb +++ b/cron/lib/symbiosis/crontab.rb @@ -6,8 +6,8 @@ # Modifications were made by Patrick J Cherry for the # Bytemark Symbiosis system # -# HISTORY -# +# HISTORY +# # 2010-06-17: Reworked for Symbiosis # 2001-01-04: (BUG) camma and slash were misinterpreted # 2000-12-31: replaced Array#filter with collect! @@ -20,7 +20,7 @@ # COPYRIGHT # # This code is released under the same terms as Ruby itself. See LICENCE for -# more details. +# more details. # # (c) 2000-1 Kentaro Goto # (c) 2010-2012 Bytemark Computer Consulting Ltd @@ -30,17 +30,17 @@ require 'net/smtp' require 'date' require 'time' +require 'English' # # Additional methods for DateTime # class DateTime - # # Return a string of self in the standard "YYYY-MM-DD hh:mm" format. # def iso8601 - "%04i-%02i-%02i %02i:%02i" % [ year, month, day, hour, min ] + format('%04i-%02i-%02i %02i:%02i', year, month, day, hour, min) end # @@ -52,13 +52,11 @@ def to_time end module Symbiosis - # # A class representing a Crontab. - # + # class Crontab - - # + # # The array of crontab records # attr_reader :records @@ -68,7 +66,7 @@ class Crontab # read # attr_reader :filename - + # # The original string input to parse. # @@ -81,9 +79,9 @@ class Crontab # # This takes an argument of a crontab in a string, or a filename. If a - # filename is given, it will be read. Otherwise the string will be parsed. + # filename is given, it will be read. Otherwise the string will be parsed. # - def initialize(string_or_filename = "") + def initialize(string_or_filename = '') # Must be a string! raise ArgumentError unless string_or_filename.is_a?(String) @@ -91,18 +89,18 @@ def initialize(string_or_filename = "") @environment = {} if File.exist?(string_or_filename) @filename = string_or_filename - @crontab = File.open(string_or_filename){|fh| fh.read} + @crontab = File.open(string_or_filename, &:read) else - @filename = "string input" + @filename = 'string input' @crontab = string_or_filename end @mail_output = true - @mail_command = "/usr/lib/sendmail -t" + @mail_command = '/usr/lib/sendmail -t' parse(@crontab) end - # + # # An iterator for each record. # def each(&block) @@ -113,7 +111,7 @@ def each(&block) # This sets the flag to mail output # def mail_output=(n) - raise ArgumentError unless n.is_a?(TrueClass) or n.is_a?(FalseClass) + raise ArgumentError unless n.is_a?(TrueClass) || n.is_a?(FalseClass) @mail_output = n end @@ -122,20 +120,20 @@ def mail_output=(n) # next run. # def test(t = Time.now) - cron_env = @environment.merge(ENV){|k,o,n| o} - puts "Environment\n"+"-"*72 + cron_env = @environment.merge(ENV) { |_k, o, _n| o } + puts "Environment\n" + '-' * 72 %w(HOME LOGNAME PATH MAILTO).each do |k| puts "#{k} = #{cron_env[k]}" end - puts "="*72+"\n\n" - puts "Jobs next due -- Local time #{t.iso8601}\n"+"-"*72 - puts ("%-20s" % "Date" ) + "Command" - puts "-"*72 + puts '=' * 72 + "\n\n" + puts "Jobs next due -- Local time #{t.iso8601}\n" + '-' * 72 + puts format('%-20s', 'Date') + 'Command' + puts '-' * 72 @records.each do |record| n = record.next_due(t) - puts ("%-20s" % (n.nil? ? "** NEVER **" : n.iso8601))+record.command + puts format('%-20s', (n.nil? ? '** NEVER **' : n.iso8601)) + record.command end - puts "="*72 + puts '=' * 72 end # @@ -143,26 +141,25 @@ def test(t = Time.now) # def run old_env = {} - @environment.each do |k,v| + @environment.each do |k, v| next unless %w(MAILTO PATH).include?(k) old_env[k] = (ENV[k].nil? ? nil : ENV[k]) ENV[k] = v end - output = [] + output = [] - @records.select{|record| record.ready?}.each do |record| + @records.select(&:ready?).each do |record| this_output = record.run - if this_output.length > 0 - output << record.command+":\n" - output += this_output - output << "\n" - end + next if this_output.empty? + output << record.command + ":\n" + output += this_output + output << "\n" end # restore environment - old_env.each do |k,v| + old_env.each do |k, v| if v.nil? - ENV.delete(k) + ENV.delete(k) else ENV[k] = v end @@ -170,22 +167,22 @@ def run return if output.empty? - if @environment['MAILTO'] and !@environment['MAILTO'].to_s.empty? - cron_env = @environment.merge(ENV){|k,o,n| o} + if @environment['MAILTO'] && !@environment['MAILTO'].to_s.empty? + cron_env = @environment.merge(ENV) { |_k, o, _n| o } mail = [] mail << "To: #{@environment['MAILTO']}" mail << "Subject: Cron output for #{@filename}" %w(SHELL PATH HOME LOGNAME).each do |k| - mail << "X-Cron-Env: <#{k}=#{cron_env[k]}>" if ENV.has_key?(k) + mail << "X-Cron-Env: <#{k}=#{cron_env[k]}>" if ENV.key?(k) end mail << "Date: #{Time.now.rfc2822}" - mail << "" + mail << '' mail << output.join if @mail_output - IO.popen(@mail_command,"w+") do |pipe| + IO.popen(@mail_command, 'w+') do |pipe| pipe.write mail.join("\n") pipe.close - end + end else puts mail.join("\n") end @@ -198,32 +195,31 @@ def run # Returns any records that are ready to run now. # def grep(now = Time.now) - @records.select{|record| record.ready?(now)} + @records.select { |record| record.ready?(now) } end private def parse(str) - str.split($/).each{|line| + str.split($INPUT_RECORD_SEPARATOR).each do |line| line.chomp! # Skip if line begins with a hash or is all spaces or empty. - next if line =~ /\A([\s#].*|\s*)\Z/ + next if line =~ /\A([\s#].*|\s*)\Z/ # Skip unsupported lines if line =~ /^\s*@reboot/ - warn "cronjobs to be invoked at @reboot-time are not supported." + warn 'cronjobs to be invoked at @reboot-time are not supported.' next end if line =~ /\A([A-Z]+)\s*=\s*(.*)\Z/ - @environment[$1] = $2 + @environment[Regexp.last_match(1)] = Regexp.last_match(2) else @records << CrontabRecord.parse(line) end - } + end end - end # @@ -235,58 +231,54 @@ class CrontabFormatError < StandardError; end # This class represents and individual line of a crontab # class CrontabRecord - # # Weekday names that can be used in records # - WDAY = %w(sun mon tue wed thu fri sat) + WDAY = %w(sun mon tue wed thu fri sat).freeze # # Month names that can be used in records. # - MON = %w(jan feb mar apr may jun jul aug sep oct nov dec) + MON = %w(jan feb mar apr may jun jul aug sep oct nov dec).freeze # # Hash of names that correspond to @ shortcuts. # SHORTCUTS = { - "(?:year|annual)ly" => "0 0 1 1 *", - "monthly" => "0 0 1 * *", - "weekly" => "0 0 * * 0", - "(?:daily|midnight)" => "0 0 * * *", - "hourly" => "0 * * * *" - } + '(?:year|annual)ly' => '0 0 1 1 *', + 'monthly' => '0 0 1 * *', + 'weekly' => '0 0 * * 0', + '(?:daily|midnight)' => '0 0 * * *', + 'hourly' => '0 * * * *' + }.freeze # # Create a new CrontabRecord using a string. Raises CrontabFormatError if # the string parsing fails. # def self.parse(str) - if str =~ /\A(?:@(?:#{SHORTCUTS.keys.join("|")})\s+|(?:\S+\s+){5})(.*)\Z$/ - - # pick off the last match - command = $+ - - # replace any shortcuts - SHORTCUTS.collect{|shortcut, snippet| str.sub!(/\A\s*@#{shortcut}/, snippet)} - - min, hour, mday, mon, wday = str.split(/\s+/).first(5) - - # This regexp makes sure we start at a word boundary (\b), and can take - # names longer than the ones specified. - wday = wday.downcase.gsub(/\b(#{WDAY.join("|")})[a-z]*/){ - WDAY.index($1) - } - - # Same as above, but have to add one, as months start at 1 not 0. - mon = mon.downcase.gsub(/\b(#{MON.join("|")})[a-z]*/){ - MON.index($1)+1 - } - - self.new(min, hour, mday, mon, wday, command) - else - raise CrontabFormatError, "Badly formatted line: #{str.inspect}" + raise CrontabFormatError, "Badly formatted line: #{str.inspect}" unless str =~ /\A(?:@(?:#{SHORTCUTS.keys.join("|")})\s+|(?:\S+\s+){5})(.*)\Z$/ + + # pick off the last match + command = $+ + + # replace any shortcuts + SHORTCUTS.collect { |shortcut, snippet| str.sub!(/\A\s*@#{shortcut}/, snippet) } + + min, hour, mday, mon, wday = str.split(/\s+/).first(5) + + # This regexp makes sure we start at a word boundary (\b), and can take + # names longer than the ones specified. + wday = wday.downcase.gsub(/\b(#{WDAY.join("|")})[a-z]*/) do + WDAY.index(Regexp.last_match(1)) end + + # Same as above, but have to add one, as months start at 1 not 0. + mon = mon.downcase.gsub(/\b(#{MON.join("|")})[a-z]*/) do + MON.index(Regexp.last_match(1)) + 1 + end + + new(min, hour, mday, mon, wday, command) end attr_reader :min, :hour, :mday, :mon, :wday, :command @@ -294,7 +286,7 @@ def self.parse(str) # # Create a new CrontabRecord, setting the minute, hour, month-day, month, # week-day and command. Raises a CrontabFormatError if any of the - # arguments fail to parse. + # arguments fail to parse. # def initialize(min, hour, mday, mon, wday, command) @min = parse_field(min, 0, 59) @@ -304,13 +296,13 @@ def initialize(min, hour, mday, mon, wday, command) @wday = parse_field(wday, 0, 7) # normalize weekdays - @wday = @wday.collect{|w| w == 7 ? 0 : w }.sort.uniq + @wday = @wday.collect { |w| w == 7 ? 0 : w }.sort.uniq # # If both mday and wday are restricted, then match on either mday or # wday. # - @lazy_mday_wday_match = (@mday != (1..31).to_a and @wday != (0..6).to_a) + @lazy_mday_wday_match = ((@mday != (1..31).to_a) && (@wday != (0..6).to_a)) self.command = command end @@ -319,27 +311,27 @@ def initialize(min, hour, mday, mon, wday, command) # Set the command to c. Accepts a String or Proc. # def command=(c) - raise ArgumentError, "Commands must be a String or a Proc" unless c.is_a?(String) or c.is_a?(Proc) + raise ArgumentError, 'Commands must be a String or a Proc' unless c.is_a?(String) || c.is_a?(Proc) @command = c end # # Returns true if the record should be run at time set by now. # - def ready?(now = Time.now) - now = now.to_time + def ready?(now = Time.now) + now = now.to_time if @lazy_mday_wday_match - min.include? now.min and - hour.include? now.hour and - mon.include? now.mon and - ( mday.include? now.mday or - wday.include? now.wday ) + min.include?(now.min) && + hour.include?(now.hour) && + mon.include?(now.mon) && + (mday.include?(now.mday) || + wday.include?(now.wday)) else - min.include? now.min and - hour.include? now.hour and - mon.include? now.mon and - mday.include? now.mday and - wday.include? now.wday + min.include?(now.min) && + hour.include?(now.hour) && + mon.include?(now.mon) && + mday.include?(now.mday) && + wday.include?(now.wday) end end @@ -352,7 +344,7 @@ def next_due(now = Time.now) time = now.to_time orig_time = time - while !ready?(time) + until ready?(time) # find the next minute that matches unless min.include?(time.min) ind = (min + [time.min]).sort.index(time.min) @@ -361,9 +353,9 @@ def next_due(now = Time.now) # Roll on time to the beginning of the next hour # time += 3600 - time = Time.local(time.year, time.mon, time.day, time.hour, time.min) + time = Time.local(time.year, time.mon, time.day, time.hour, time.min) else - time = Time.local(time.year, time.mon, time.day, time.hour, min[ind]) + time = Time.local(time.year, time.mon, time.day, time.hour, min[ind]) end end @@ -376,22 +368,22 @@ def next_due(now = Time.now) dtime = time.to_date + 1 time = Time.local(dtime.year, dtime.mon, dtime.day) else - time = Time.local(time.year, time.mon, time.day, hour[ind], time.min, 0) + time = Time.local(time.year, time.mon, time.day, hour[ind], time.min, 0) end - end - + end + time_a = time_b = nil # find the next month or week day that matches - if (!mday.include?(time.mday) or @lazy_mday_wday_match) + if !mday.include?(time.mday) || @lazy_mday_wday_match ind = (mday + [time.mday]).sort.index(time.mday) if mday.length == ind dtime = time.to_date >> 1 - time_a = Time.local(dtime.year, dtime.mon, dtime.mday) + time_a = Time.local(dtime.year, dtime.mon, dtime.mday) else begin - time_a = Time.local(time.year, time.mon, mday[ind], time.hour, time.min) + time_a = Time.local(time.year, time.mon, mday[ind], time.hour, time.min) rescue ArgumentError dtime = time.to_date >> 1 time_a = Time.local(dtime.year, dtime.mon) @@ -401,7 +393,7 @@ def next_due(now = Time.now) time = time_a unless @lazy_mday_wday_match end - if (!wday.include?(time.wday) or @lazy_mday_wday_match) + if !wday.include?(time.wday) || @lazy_mday_wday_match ind = (wday + [time.wday]).sort.index(time.wday) if wday.length == ind @@ -409,14 +401,14 @@ def next_due(now = Time.now) dtime = time.to_date + (7 - time.wday + wday.first) time_b = Time.local(dtime.year, dtime.mon, dtime.mday) else - dtime = time.to_date + (wday.first - time.wday) + dtime = time.to_date + (wday.first - time.wday) time_b = Time.local(dtime.year, dtime.mon, dtime.mday, time.hour, time.min) end time = time_b unless @lazy_mday_wday_match end - if @lazy_mday_wday_match and time_a.is_a?(Time) and time_b.is_a?(Time) + if @lazy_mday_wday_match && time_a.is_a?(Time) && time_b.is_a?(Time) time = (time_a < time_b ? time_a : time_b) end @@ -425,7 +417,7 @@ def next_due(now = Time.now) ind = (mon + [time.mon]).sort.index(time.mon) if mon.length == ind - # Roll on time to the beginning of the next year + # Roll on time to the beginning of the next year time = Time.local(time.year + 1) else begin @@ -436,7 +428,7 @@ def next_due(now = Time.now) end end end - + # Break if we get 30 years into the future! if time.year - orig_time.year > 30 time = nil @@ -447,74 +439,67 @@ def next_due(now = Time.now) time end - # # Run the command. Returns an arry of strings as output. # def run # OK to run we're just going to run the command in a pipe. # - ret = IO.popen(@command) { |pipe| pipe.readlines } + ret = IO.popen(@command, &:readlines) # Check for a duff exit status. - if !$?.success? - ret << "Command failed with exit status #{$?.exitstatus}\n" + unless $CHILD_STATUS.success? + ret << "Command failed with exit status #{$CHILD_STATUS.exitstatus}\n" end ret end - + private def parse_field(str, first, last) - str.split(",").map do |entry| - every, f, l = nil - + str.split(',').map do |entry| # - # Split the field, assuming it looks like "0-9/4". + # Split the field, assuming it looks like "0-9/4". # - if entry.strip =~ /(\*|\d+)(?:\-(\d+))?(?:\/(\d+))?/ - f,l,every = [$1, $2, $3] - every = (every ? every.to_i : 1) - raise CrontabFormatError.new "Bad specifier #{every.inspect} in #{str.inspect}" if every < 1 - else - raise CrontabFormatError.new "Bad entry #{entry.inspect} in field #{str.inspect}" - end - - range = if f == "*" - first..last - else - l = f if l.nil? - - # make sure we have integers - f,l = [f,l].collect do |n| - - if n.is_a?(String) - # Make sure we're going to get a sensible answer - raise CrontabFormatError.new "Bad field #{n.inspect} in #{str}" unless n =~ /^\d+$/ - n = n.to_i - end - - # Make sure we've got an integer now - raise CrontabFormatError.new "Bad field #{n.inspect} in #{str}" unless n.is_a?(Integer) - - # make sure everything is within ranges - raise CrontabFormatError.new "out of range (#{n} for #{first}..#{last})" unless (first..last).include?(n) - - n - end - - # deal with out-of-order ranges - if l < f - (f..last).to_a + (first..l).to_a - else - f..l - end - end - - range.to_a.find_all{|i| (i - first) % every == 0} - + raise CrontabFormatError, "Bad entry #{entry.inspect} in field #{str.inspect}" unless entry.strip =~ /(\*|\d+)(?:\-(\d+))?(?:\/(\d+))?/ + + f = Regexp.last_match(1) + l = Regexp.last_match(2) + every = Regexp.last_match(3) + every = (every ? every.to_i : 1) + raise CrontabFormatError, "Bad specifier #{every.inspect} in #{str.inspect}" if every < 1 + + range = if f == '*' + first..last + else + l = f if l.nil? + + # make sure we have integers + f, l = [f, l].collect do |n| + if n.is_a?(String) + # Make sure we're going to get a sensible answer + raise CrontabFormatError, "Bad field #{n.inspect} in #{str}" unless n =~ /^\d+$/ + n = n.to_i + end + + # Make sure we've got an integer now + raise CrontabFormatError, "Bad field #{n.inspect} in #{str}" unless n.is_a?(Integer) + + # make sure everything is within ranges + raise CrontabFormatError, "out of range (#{n} for #{first}..#{last})" unless (first..last).cover?(n) + + n + end + + # deal with out-of-order ranges + if l < f + (f..last).to_a + (first..l).to_a + else + f..l + end + end + + range.to_a.find_all { |i| ((i - first) % every).zero? } end.flatten.sort.uniq end - end - end From 1f068c06f7a2da196fd5ec967851af4f9204858e Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 7 Jun 2017 16:05:17 +0100 Subject: [PATCH 16/17] Revert "Rubocop'd" This reverts commit 14c601eb32f38d0cd9d656bead88871198797050. Committed in error --- cron/lib/symbiosis/crontab.rb | 311 ++++++++++++++++++---------------- 1 file changed, 163 insertions(+), 148 deletions(-) diff --git a/cron/lib/symbiosis/crontab.rb b/cron/lib/symbiosis/crontab.rb index 772a0d8b..dddae4f8 100644 --- a/cron/lib/symbiosis/crontab.rb +++ b/cron/lib/symbiosis/crontab.rb @@ -6,8 +6,8 @@ # Modifications were made by Patrick J Cherry for the # Bytemark Symbiosis system # -# HISTORY -# +# HISTORY +# # 2010-06-17: Reworked for Symbiosis # 2001-01-04: (BUG) camma and slash were misinterpreted # 2000-12-31: replaced Array#filter with collect! @@ -20,7 +20,7 @@ # COPYRIGHT # # This code is released under the same terms as Ruby itself. See LICENCE for -# more details. +# more details. # # (c) 2000-1 Kentaro Goto # (c) 2010-2012 Bytemark Computer Consulting Ltd @@ -30,17 +30,17 @@ require 'net/smtp' require 'date' require 'time' -require 'English' # # Additional methods for DateTime # class DateTime + # # Return a string of self in the standard "YYYY-MM-DD hh:mm" format. # def iso8601 - format('%04i-%02i-%02i %02i:%02i', year, month, day, hour, min) + "%04i-%02i-%02i %02i:%02i" % [ year, month, day, hour, min ] end # @@ -52,11 +52,13 @@ def to_time end module Symbiosis + # # A class representing a Crontab. - # + # class Crontab - # + + # # The array of crontab records # attr_reader :records @@ -66,7 +68,7 @@ class Crontab # read # attr_reader :filename - + # # The original string input to parse. # @@ -79,9 +81,9 @@ class Crontab # # This takes an argument of a crontab in a string, or a filename. If a - # filename is given, it will be read. Otherwise the string will be parsed. + # filename is given, it will be read. Otherwise the string will be parsed. # - def initialize(string_or_filename = '') + def initialize(string_or_filename = "") # Must be a string! raise ArgumentError unless string_or_filename.is_a?(String) @@ -89,18 +91,18 @@ def initialize(string_or_filename = '') @environment = {} if File.exist?(string_or_filename) @filename = string_or_filename - @crontab = File.open(string_or_filename, &:read) + @crontab = File.open(string_or_filename){|fh| fh.read} else - @filename = 'string input' + @filename = "string input" @crontab = string_or_filename end @mail_output = true - @mail_command = '/usr/lib/sendmail -t' + @mail_command = "/usr/lib/sendmail -t" parse(@crontab) end - # + # # An iterator for each record. # def each(&block) @@ -111,7 +113,7 @@ def each(&block) # This sets the flag to mail output # def mail_output=(n) - raise ArgumentError unless n.is_a?(TrueClass) || n.is_a?(FalseClass) + raise ArgumentError unless n.is_a?(TrueClass) or n.is_a?(FalseClass) @mail_output = n end @@ -120,20 +122,20 @@ def mail_output=(n) # next run. # def test(t = Time.now) - cron_env = @environment.merge(ENV) { |_k, o, _n| o } - puts "Environment\n" + '-' * 72 + cron_env = @environment.merge(ENV){|k,o,n| o} + puts "Environment\n"+"-"*72 %w(HOME LOGNAME PATH MAILTO).each do |k| puts "#{k} = #{cron_env[k]}" end - puts '=' * 72 + "\n\n" - puts "Jobs next due -- Local time #{t.iso8601}\n" + '-' * 72 - puts format('%-20s', 'Date') + 'Command' - puts '-' * 72 + puts "="*72+"\n\n" + puts "Jobs next due -- Local time #{t.iso8601}\n"+"-"*72 + puts ("%-20s" % "Date" ) + "Command" + puts "-"*72 @records.each do |record| n = record.next_due(t) - puts format('%-20s', (n.nil? ? '** NEVER **' : n.iso8601)) + record.command + puts ("%-20s" % (n.nil? ? "** NEVER **" : n.iso8601))+record.command end - puts '=' * 72 + puts "="*72 end # @@ -141,25 +143,26 @@ def test(t = Time.now) # def run old_env = {} - @environment.each do |k, v| + @environment.each do |k,v| next unless %w(MAILTO PATH).include?(k) old_env[k] = (ENV[k].nil? ? nil : ENV[k]) ENV[k] = v end - output = [] + output = [] - @records.select(&:ready?).each do |record| + @records.select{|record| record.ready?}.each do |record| this_output = record.run - next if this_output.empty? - output << record.command + ":\n" - output += this_output - output << "\n" + if this_output.length > 0 + output << record.command+":\n" + output += this_output + output << "\n" + end end # restore environment - old_env.each do |k, v| + old_env.each do |k,v| if v.nil? - ENV.delete(k) + ENV.delete(k) else ENV[k] = v end @@ -167,22 +170,22 @@ def run return if output.empty? - if @environment['MAILTO'] && !@environment['MAILTO'].to_s.empty? - cron_env = @environment.merge(ENV) { |_k, o, _n| o } + if @environment['MAILTO'] and !@environment['MAILTO'].to_s.empty? + cron_env = @environment.merge(ENV){|k,o,n| o} mail = [] mail << "To: #{@environment['MAILTO']}" mail << "Subject: Cron output for #{@filename}" %w(SHELL PATH HOME LOGNAME).each do |k| - mail << "X-Cron-Env: <#{k}=#{cron_env[k]}>" if ENV.key?(k) + mail << "X-Cron-Env: <#{k}=#{cron_env[k]}>" if ENV.has_key?(k) end mail << "Date: #{Time.now.rfc2822}" - mail << '' + mail << "" mail << output.join if @mail_output - IO.popen(@mail_command, 'w+') do |pipe| + IO.popen(@mail_command,"w+") do |pipe| pipe.write mail.join("\n") pipe.close - end + end else puts mail.join("\n") end @@ -195,31 +198,32 @@ def run # Returns any records that are ready to run now. # def grep(now = Time.now) - @records.select { |record| record.ready?(now) } + @records.select{|record| record.ready?(now)} end private def parse(str) - str.split($INPUT_RECORD_SEPARATOR).each do |line| + str.split($/).each{|line| line.chomp! # Skip if line begins with a hash or is all spaces or empty. - next if line =~ /\A([\s#].*|\s*)\Z/ + next if line =~ /\A([\s#].*|\s*)\Z/ # Skip unsupported lines if line =~ /^\s*@reboot/ - warn 'cronjobs to be invoked at @reboot-time are not supported.' + warn "cronjobs to be invoked at @reboot-time are not supported." next end if line =~ /\A([A-Z]+)\s*=\s*(.*)\Z/ - @environment[Regexp.last_match(1)] = Regexp.last_match(2) + @environment[$1] = $2 else @records << CrontabRecord.parse(line) end - end + } end + end # @@ -231,54 +235,58 @@ class CrontabFormatError < StandardError; end # This class represents and individual line of a crontab # class CrontabRecord + # # Weekday names that can be used in records # - WDAY = %w(sun mon tue wed thu fri sat).freeze + WDAY = %w(sun mon tue wed thu fri sat) # # Month names that can be used in records. # - MON = %w(jan feb mar apr may jun jul aug sep oct nov dec).freeze + MON = %w(jan feb mar apr may jun jul aug sep oct nov dec) # # Hash of names that correspond to @ shortcuts. # SHORTCUTS = { - '(?:year|annual)ly' => '0 0 1 1 *', - 'monthly' => '0 0 1 * *', - 'weekly' => '0 0 * * 0', - '(?:daily|midnight)' => '0 0 * * *', - 'hourly' => '0 * * * *' - }.freeze + "(?:year|annual)ly" => "0 0 1 1 *", + "monthly" => "0 0 1 * *", + "weekly" => "0 0 * * 0", + "(?:daily|midnight)" => "0 0 * * *", + "hourly" => "0 * * * *" + } # # Create a new CrontabRecord using a string. Raises CrontabFormatError if # the string parsing fails. # def self.parse(str) - raise CrontabFormatError, "Badly formatted line: #{str.inspect}" unless str =~ /\A(?:@(?:#{SHORTCUTS.keys.join("|")})\s+|(?:\S+\s+){5})(.*)\Z$/ - - # pick off the last match - command = $+ - - # replace any shortcuts - SHORTCUTS.collect { |shortcut, snippet| str.sub!(/\A\s*@#{shortcut}/, snippet) } - - min, hour, mday, mon, wday = str.split(/\s+/).first(5) - - # This regexp makes sure we start at a word boundary (\b), and can take - # names longer than the ones specified. - wday = wday.downcase.gsub(/\b(#{WDAY.join("|")})[a-z]*/) do - WDAY.index(Regexp.last_match(1)) - end - - # Same as above, but have to add one, as months start at 1 not 0. - mon = mon.downcase.gsub(/\b(#{MON.join("|")})[a-z]*/) do - MON.index(Regexp.last_match(1)) + 1 + if str =~ /\A(?:@(?:#{SHORTCUTS.keys.join("|")})\s+|(?:\S+\s+){5})(.*)\Z$/ + + # pick off the last match + command = $+ + + # replace any shortcuts + SHORTCUTS.collect{|shortcut, snippet| str.sub!(/\A\s*@#{shortcut}/, snippet)} + + min, hour, mday, mon, wday = str.split(/\s+/).first(5) + + # This regexp makes sure we start at a word boundary (\b), and can take + # names longer than the ones specified. + wday = wday.downcase.gsub(/\b(#{WDAY.join("|")})[a-z]*/){ + WDAY.index($1) + } + + # Same as above, but have to add one, as months start at 1 not 0. + mon = mon.downcase.gsub(/\b(#{MON.join("|")})[a-z]*/){ + MON.index($1)+1 + } + + self.new(min, hour, mday, mon, wday, command) + else + raise CrontabFormatError, "Badly formatted line: #{str.inspect}" end - - new(min, hour, mday, mon, wday, command) end attr_reader :min, :hour, :mday, :mon, :wday, :command @@ -286,7 +294,7 @@ def self.parse(str) # # Create a new CrontabRecord, setting the minute, hour, month-day, month, # week-day and command. Raises a CrontabFormatError if any of the - # arguments fail to parse. + # arguments fail to parse. # def initialize(min, hour, mday, mon, wday, command) @min = parse_field(min, 0, 59) @@ -296,13 +304,13 @@ def initialize(min, hour, mday, mon, wday, command) @wday = parse_field(wday, 0, 7) # normalize weekdays - @wday = @wday.collect { |w| w == 7 ? 0 : w }.sort.uniq + @wday = @wday.collect{|w| w == 7 ? 0 : w }.sort.uniq # # If both mday and wday are restricted, then match on either mday or # wday. # - @lazy_mday_wday_match = ((@mday != (1..31).to_a) && (@wday != (0..6).to_a)) + @lazy_mday_wday_match = (@mday != (1..31).to_a and @wday != (0..6).to_a) self.command = command end @@ -311,27 +319,27 @@ def initialize(min, hour, mday, mon, wday, command) # Set the command to c. Accepts a String or Proc. # def command=(c) - raise ArgumentError, 'Commands must be a String or a Proc' unless c.is_a?(String) || c.is_a?(Proc) + raise ArgumentError, "Commands must be a String or a Proc" unless c.is_a?(String) or c.is_a?(Proc) @command = c end # # Returns true if the record should be run at time set by now. # - def ready?(now = Time.now) - now = now.to_time + def ready?(now = Time.now) + now = now.to_time if @lazy_mday_wday_match - min.include?(now.min) && - hour.include?(now.hour) && - mon.include?(now.mon) && - (mday.include?(now.mday) || - wday.include?(now.wday)) + min.include? now.min and + hour.include? now.hour and + mon.include? now.mon and + ( mday.include? now.mday or + wday.include? now.wday ) else - min.include?(now.min) && - hour.include?(now.hour) && - mon.include?(now.mon) && - mday.include?(now.mday) && - wday.include?(now.wday) + min.include? now.min and + hour.include? now.hour and + mon.include? now.mon and + mday.include? now.mday and + wday.include? now.wday end end @@ -344,7 +352,7 @@ def next_due(now = Time.now) time = now.to_time orig_time = time - until ready?(time) + while !ready?(time) # find the next minute that matches unless min.include?(time.min) ind = (min + [time.min]).sort.index(time.min) @@ -353,9 +361,9 @@ def next_due(now = Time.now) # Roll on time to the beginning of the next hour # time += 3600 - time = Time.local(time.year, time.mon, time.day, time.hour, time.min) + time = Time.local(time.year, time.mon, time.day, time.hour, time.min) else - time = Time.local(time.year, time.mon, time.day, time.hour, min[ind]) + time = Time.local(time.year, time.mon, time.day, time.hour, min[ind]) end end @@ -368,22 +376,22 @@ def next_due(now = Time.now) dtime = time.to_date + 1 time = Time.local(dtime.year, dtime.mon, dtime.day) else - time = Time.local(time.year, time.mon, time.day, hour[ind], time.min, 0) + time = Time.local(time.year, time.mon, time.day, hour[ind], time.min, 0) end - end - + end + time_a = time_b = nil # find the next month or week day that matches - if !mday.include?(time.mday) || @lazy_mday_wday_match + if (!mday.include?(time.mday) or @lazy_mday_wday_match) ind = (mday + [time.mday]).sort.index(time.mday) if mday.length == ind dtime = time.to_date >> 1 - time_a = Time.local(dtime.year, dtime.mon, dtime.mday) + time_a = Time.local(dtime.year, dtime.mon, dtime.mday) else begin - time_a = Time.local(time.year, time.mon, mday[ind], time.hour, time.min) + time_a = Time.local(time.year, time.mon, mday[ind], time.hour, time.min) rescue ArgumentError dtime = time.to_date >> 1 time_a = Time.local(dtime.year, dtime.mon) @@ -393,7 +401,7 @@ def next_due(now = Time.now) time = time_a unless @lazy_mday_wday_match end - if !wday.include?(time.wday) || @lazy_mday_wday_match + if (!wday.include?(time.wday) or @lazy_mday_wday_match) ind = (wday + [time.wday]).sort.index(time.wday) if wday.length == ind @@ -401,14 +409,14 @@ def next_due(now = Time.now) dtime = time.to_date + (7 - time.wday + wday.first) time_b = Time.local(dtime.year, dtime.mon, dtime.mday) else - dtime = time.to_date + (wday.first - time.wday) + dtime = time.to_date + (wday.first - time.wday) time_b = Time.local(dtime.year, dtime.mon, dtime.mday, time.hour, time.min) end time = time_b unless @lazy_mday_wday_match end - if @lazy_mday_wday_match && time_a.is_a?(Time) && time_b.is_a?(Time) + if @lazy_mday_wday_match and time_a.is_a?(Time) and time_b.is_a?(Time) time = (time_a < time_b ? time_a : time_b) end @@ -417,7 +425,7 @@ def next_due(now = Time.now) ind = (mon + [time.mon]).sort.index(time.mon) if mon.length == ind - # Roll on time to the beginning of the next year + # Roll on time to the beginning of the next year time = Time.local(time.year + 1) else begin @@ -428,7 +436,7 @@ def next_due(now = Time.now) end end end - + # Break if we get 30 years into the future! if time.year - orig_time.year > 30 time = nil @@ -439,67 +447,74 @@ def next_due(now = Time.now) time end + # # Run the command. Returns an arry of strings as output. # def run # OK to run we're just going to run the command in a pipe. # - ret = IO.popen(@command, &:readlines) + ret = IO.popen(@command) { |pipe| pipe.readlines } # Check for a duff exit status. - unless $CHILD_STATUS.success? - ret << "Command failed with exit status #{$CHILD_STATUS.exitstatus}\n" + if !$?.success? + ret << "Command failed with exit status #{$?.exitstatus}\n" end ret end - + private def parse_field(str, first, last) - str.split(',').map do |entry| + str.split(",").map do |entry| + every, f, l = nil + # - # Split the field, assuming it looks like "0-9/4". + # Split the field, assuming it looks like "0-9/4". # - raise CrontabFormatError, "Bad entry #{entry.inspect} in field #{str.inspect}" unless entry.strip =~ /(\*|\d+)(?:\-(\d+))?(?:\/(\d+))?/ - - f = Regexp.last_match(1) - l = Regexp.last_match(2) - every = Regexp.last_match(3) - every = (every ? every.to_i : 1) - raise CrontabFormatError, "Bad specifier #{every.inspect} in #{str.inspect}" if every < 1 - - range = if f == '*' - first..last - else - l = f if l.nil? - - # make sure we have integers - f, l = [f, l].collect do |n| - if n.is_a?(String) - # Make sure we're going to get a sensible answer - raise CrontabFormatError, "Bad field #{n.inspect} in #{str}" unless n =~ /^\d+$/ - n = n.to_i - end - - # Make sure we've got an integer now - raise CrontabFormatError, "Bad field #{n.inspect} in #{str}" unless n.is_a?(Integer) - - # make sure everything is within ranges - raise CrontabFormatError, "out of range (#{n} for #{first}..#{last})" unless (first..last).cover?(n) - - n - end - - # deal with out-of-order ranges - if l < f - (f..last).to_a + (first..l).to_a - else - f..l - end - end - - range.to_a.find_all { |i| ((i - first) % every).zero? } + if entry.strip =~ /(\*|\d+)(?:\-(\d+))?(?:\/(\d+))?/ + f,l,every = [$1, $2, $3] + every = (every ? every.to_i : 1) + raise CrontabFormatError.new "Bad specifier #{every.inspect} in #{str.inspect}" if every < 1 + else + raise CrontabFormatError.new "Bad entry #{entry.inspect} in field #{str.inspect}" + end + + range = if f == "*" + first..last + else + l = f if l.nil? + + # make sure we have integers + f,l = [f,l].collect do |n| + + if n.is_a?(String) + # Make sure we're going to get a sensible answer + raise CrontabFormatError.new "Bad field #{n.inspect} in #{str}" unless n =~ /^\d+$/ + n = n.to_i + end + + # Make sure we've got an integer now + raise CrontabFormatError.new "Bad field #{n.inspect} in #{str}" unless n.is_a?(Integer) + + # make sure everything is within ranges + raise CrontabFormatError.new "out of range (#{n} for #{first}..#{last})" unless (first..last).include?(n) + + n + end + + # deal with out-of-order ranges + if l < f + (f..last).to_a + (first..l).to_a + else + f..l + end + end + + range.to_a.find_all{|i| (i - first) % every == 0} + end.flatten.sort.uniq end + end + end From 88a496cbcde13123c20dc3681d0fa3d24b136d54 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Tue, 13 Jun 2017 15:27:15 +0100 Subject: [PATCH 17/17] Update symbiosis-monit-failure-email to use `-o cat` for email output. --- monit/sbin/symbiosis-monit-failure-email | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monit/sbin/symbiosis-monit-failure-email b/monit/sbin/symbiosis-monit-failure-email index 6185dd36..f0b1c4f8 100755 --- a/monit/sbin/symbiosis-monit-failure-email +++ b/monit/sbin/symbiosis-monit-failure-email @@ -5,4 +5,4 @@ set -e args="--since=today" [ -e "/var/tmp/symbiosis-monit.cursor" ] && args="--after-cursor=$(