root/lang/ruby/misc/periodic_forwarder

Revision 17386, 3.3 kB (checked in by wtnabe, 11 months ago)

lang/ruby/misc/periodic_forwarder: periodic, run-parts を任意のディレクトリで実行しやすくするツールを書いてみた

  • Property svn:executable set to *
Line 
1#! /usr/bin/env ruby
2# -*- mode: ruby; coding: mule-utf-8 -*-
3
4require 'pathname'
5require 'optparse'
6#require 'const_loader'
7
8#
9# = periodic-forwarder
10#
11# スクリプトに置かれているディレクトリに応じて、該当する periodic なディ
12# レクトリを指定パス内から探し出し、これを run-parts あるいは periodic
13# で実行する
14#
15# ex)
16#
17#  /etc/cron.daily/THIS_SCRIPT ->
18#     periodic #{BASE_DIR}/SITE/#{FILLING_PATH}/daily/
19#
20# THIS_SCRIPT は link で構わない。APPEND を与えればリダイレクトやパイプに
21# よって結果を処理することも可能。
22#
23# == requirements
24# `which` , and `periodic` or `run-parts` command
25#
26
27Version = 0.1
28
29class PeriodicForwarder
30#  include ConstLoader
31
32  def initialize
33    @opt  = {}
34
35    @conf = {
36      'append'       => nil,
37      'base_dir'     => nil,
38      'filling_path' => nil,
39    }
40
41    @periodic        = nil
42    @periodic_runner = periodic_runner
43  end
44
45  def run()
46    begin
47      load_conf
48    rescue
49    end
50
51    opts().parse!( ARGV )
52    @period = period( parent_dir )
53    exec( collect_periodic_dirs )
54  end
55
56  #
57  # periodic / run-parts の判別
58  #
59  def periodic_runner
60    return system( 'which run-parts > /dev/null' ) ? 'run-parts' : 'periodic'
61  end
62
63  #
64  # 指定ディレクトリの親ディレクトリ
65  #
66  # 無指定の場合はスクリプト自身の置かれているディレクトリ
67  #
68  def parent_dir( dir = nil )
69    dir = ( dir.nil? ) ? File.expand_path( __FILE__ ) : dir
70
71    return Pathname.new( dir ).parent.basename.to_s
72  end
73
74  #
75  # 指定ディレクトリの意味する期間
76  #
77  def period( dir )
78    period = nil
79
80    if ( /cron\.(.*)/ =~ dir )
81      period = $1
82    else
83      period = dir
84    end
85
86    return period
87  end
88
89  #
90  # base_dir 以下で @periodic と同じ名前を持つディレクトリを集める
91  #
92  def collect_periodic_dirs( base_dir = nil )
93    dir = ( base_dir || @conf['base_dir'] )
94
95    if ( dir.nil? )
96      abort( 'base_dir is not defined.' )
97    end
98
99    dirs = []
100    Dir.foreach( dir ) { |e|
101      target = File.expand_path( File.join( dir, e.to_s, @conf['filling_path'].to_s, @period.to_s ) ) + '/'
102      if ( File.exist?( target ) and File.directory?( target ) )
103        dirs.push( target )
104      end
105    }
106
107    return dirs
108  end
109
110  #
111  # 対象ディレクトリ群に対して片っ端から @periodic を実行
112  #
113  # [Param] dirs
114  #
115  def exec( dirs )
116    dirs.each { |dir|
117      cmd = "#{@periodic_runner} #{dir}"
118      if ( @conf['append'] )
119        cmd += " #{@conf['append']}"
120      end
121      system( cmd )
122    }
123  end
124
125  #
126  # オプション定義
127  #
128  def opts
129    opt = OptionParser.new()
130#     opt.on( '-c', 'CONFIG FILE' ) { |file|
131#       if ( File.exist?( file ) )
132#         @opt['conf'] = file
133#       end
134#     }
135    opt.on( '-a', '--append=APPEND' ) { |append|
136      @conf['append'] = append
137    }
138    opt.on( '-b', '--base-dir=BASE_DIR' ) { |base_dir|
139      if ( File.exist?( base_dir ) )
140        @conf['base_dir'] = base_dir
141      end
142    }
143    opt.on( '-f', '--filling-path=FILLING_PATH' ) { |filling_path|
144      if ( File.exist?( filling_path ) )
145        @conf['filling_path'] = filling_path
146      end
147    }
148
149    return opt
150  end
151
152end # of class App
153
154if ( __FILE__ == $0 )
155  begin
156    load( File.basename( __FILE__ ) + '.conf' )
157  rescue LoadError
158  end
159  app = PeriodicForwarder.new
160  app.run()
161end
Note: See TracBrowser for help on using the browser.