pdo 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/pdo CHANGED
@@ -3,17 +3,15 @@
3
3
  lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include? lib
5
5
 
6
- #require 'pdo/version'
7
-
8
6
  require 'ostruct'
9
7
  require 'pdo'
10
8
  require 'pdo/logging'
11
9
  require 'pdo/host'
12
- require 'pdo/pdoopts'
10
+ require 'pdo/opts'
13
11
  require 'pdo/task'
14
12
  require 'pp'
15
13
 
16
- include Logging
14
+ include PDO
17
15
 
18
16
  opts = OpenStruct.new
19
17
  # setting default values
@@ -26,7 +24,7 @@ opts.nohush = false
26
24
 
27
25
  begin
28
26
  # parse ARGV; defaults in opts is overwritten if needed
29
- opts = PdoOpts.parse(ARGV, opts)
27
+ opts = Opts.parse(ARGV, opts)
30
28
  logger.debug { opts }
31
29
  rescue => err
32
30
  logger.error { "#{err.class}: #{err.message}" }
@@ -34,7 +32,6 @@ rescue => err
34
32
  exit 1
35
33
  end
36
34
 
37
- include Host
38
35
  Host.load_file opts.host_definition_file
39
36
 
40
37
  excludes = []
@@ -82,7 +79,7 @@ if opts.groups then
82
79
  end
83
80
  end
84
81
  end
85
- pdo = PDO.new(tasks, opts.thread_num)
82
+ pdo = Worker.new(tasks, opts.thread_num)
86
83
  pdo.run
87
84
  else
88
85
  opts.groups.each do |key|
data/lib/pdo.rb CHANGED
@@ -2,88 +2,90 @@
2
2
 
3
3
  require 'pdo/logging'
4
4
 
5
- class PDO
6
- include Process
7
- include Logging
5
+ module PDO
6
+ class Worker
7
+ include Process
8
+ include Logging
8
9
 
9
- def initialize(tasks, thread_num)
10
- @tasks = tasks
11
- @thread_num = thread_num
12
- end
10
+ def initialize(tasks, thread_num)
11
+ @tasks = tasks
12
+ @thread_num = thread_num
13
+ end
13
14
 
14
- def run
15
- # run first spawns a set of threads, tells them to execute the task
16
- # queue. it then loop through the current Thread list (note
17
- # Thread.list returns all running and sleeping threads), and outputs
18
- # those new data.
19
- # for the spawned threads, they execute one task, then wait for their
20
- # data to be picked up by the main thread, then do the next task.
15
+ def run
16
+ # run first spawns a set of threads, tells them to execute the task
17
+ # queue. it then loop through the current Thread list (note
18
+ # Thread.list returns all running and sleeping threads), and outputs
19
+ # those new data.
20
+ # for the spawned threads, they execute one task, then wait for their
21
+ # data to be picked up by the main thread, then do the next task.
21
22
 
22
- return 1 if @tasks.size == 0
23
+ return 1 if @tasks.size == 0
23
24
 
24
- n = @thread_num < @tasks.size ? @thread_num : @tasks.size
25
- 1.upto(n) do
26
- Thread.new do
27
- while true do
28
- logger.info "#{Thread.current.object_id} started."
29
- begin
30
- execute(@tasks.next)
31
- # presumably new data is ready, thus i stop.
32
- # main thread will read :output and then wakes me up.
33
- Thread.stop
34
- rescue
35
- logger.info "No more task for #{Thread.current.object_id}."
36
- break
25
+ n = @thread_num < @tasks.size ? @thread_num : @tasks.size
26
+ 1.upto(n) do
27
+ Thread.new do
28
+ while true do
29
+ logger.info "#{Thread.current.object_id} started."
30
+ begin
31
+ execute(@tasks.next)
32
+ # presumably new data is ready, thus i stop.
33
+ # main thread will read :output and then wakes me up.
34
+ Thread.stop
35
+ rescue
36
+ logger.info "No more task for #{Thread.current.object_id}."
37
+ break
38
+ end
37
39
  end
38
40
  end
39
41
  end
40
- end
41
42
 
42
- loop do
43
- # break because the only left thread must be the main thread.
44
- break if Thread.list.size == 1
43
+ loop do
44
+ # break because the only left thread must be the main thread.
45
+ break if Thread.list.size == 1
45
46
 
46
- Thread.list.each do |t|
47
- next if t == Thread.main
48
- if t.key? :output and t.key? :new_data and t[:new_data] then
49
- logger.info "#{t.object_id} finished."
50
- puts "=== #{t[:target]} ==="
51
- t[:output].each {|x| puts x}
52
- # puts t[:output].join('').gsub("\n", ' | ').chomp(' | ')
53
- t[:new_data] = false
54
- # wakes up the thread
55
- t.run
47
+ Thread.list.each do |t|
48
+ next if t == Thread.main
49
+ if t.key? :output and t.key? :new_data and t[:new_data] then
50
+ logger.info "#{t.object_id} finished."
51
+ puts "=== #{t[:target]} ==="
52
+ t[:output].each {|x| puts x}
53
+ # puts t[:output].join('').gsub("\n", ' | ').chomp(' | ')
54
+ t[:new_data] = false
55
+ # wakes up the thread
56
+ t.run
57
+ end
56
58
  end
57
59
  end
58
60
  end
59
- end
60
61
 
61
- def execute(task)
62
- # execute forks a child process to run the task, then saves the
63
- # output from the child process into a thread local variable, marks
64
- # the :new_data tag.
62
+ def execute(task)
63
+ # execute forks a child process to run the task, then saves the
64
+ # output from the child process into a thread local variable, marks
65
+ # the :new_data tag.
65
66
 
66
- raise "no task" if task.nil?
67
+ raise "no task" if task.nil?
67
68
 
68
- target, cmd = task
69
+ target, cmd = task
69
70
 
70
- open("|-") do |child_io|
71
- if child_io
72
- # The waitpid statement below causes the program to hang when
73
- # running some commands, such as wget.
74
- # waitpid child_io.pid
75
- Thread.current[:output] = child_io.readlines
76
- Thread.current[:new_data] = true
77
- Thread.current[:target] = target
78
- else
79
- STDIN.close
80
- STDERR.reopen(STDOUT)
81
- exec(*cmd)
71
+ open("|-") do |child_io|
72
+ if child_io
73
+ # The waitpid statement below causes the program to hang when
74
+ # running some commands, such as wget.
75
+ # waitpid child_io.pid
76
+ Thread.current[:output] = child_io.readlines
77
+ Thread.current[:new_data] = true
78
+ Thread.current[:target] = target
79
+ else
80
+ STDIN.close
81
+ STDERR.reopen(STDOUT)
82
+ exec(*cmd)
83
+ end
82
84
  end
83
- end
84
85
 
85
- end
86
+ end
86
87
 
87
- end
88
+ end # class Worker
89
+ end # module PDO
88
90
 
89
91
  # vim: set et ts=2 sts=2 sw=2 si sta :
@@ -4,186 +4,188 @@ require 'pp'
4
4
  require 'yaml'
5
5
  require_relative 'logging'
6
6
 
7
- module Host
8
-
9
- include Logging
10
-
11
- @@recursive_level = 9
12
- def self.recursive_level=(level)
13
- @@recursive_level = level
14
- end
15
- def self.recursive_level
16
- @@recursive_level
17
- end
18
-
19
- def self.load_file(def_file=nil)
20
- if def_file then
21
- files = [ def_file ]
22
- else
23
- files = [ "/etc/pdo/pdo.yaml", "#{ENV['HOME']}/.pdo/pdo.yaml", ]
24
- end
25
-
26
- hosts = {}
27
- files.each do |f|
28
- begin
29
- hosts.update(YAML::load_file(f))
30
- rescue => ex
31
- logger.warn { "#{ex.class}: #{ex.message}" }
32
- logger.debug { ex.backtrace.join "\n" }
33
- end
34
- end
35
- return @@host_hash = hosts
7
+ module PDO
8
+ module Host
36
9
 
37
- end
10
+ include Logging
38
11
 
39
- def expand_group(group, level)
40
- # given a group, recursively expand it into a list of hosts.
41
- # if the group can't expand to a list of hosts, return that group.
42
- # if there are exception expanding the group, return an empty list.
43
-
44
- hosts = []
45
-
46
- level += 1
47
- if level > @@recursive_level then
48
- logger.warn "circle detected in the host definition file."
49
- return []
12
+ @@recursive_level = 9
13
+ def self.recursive_level=(level)
14
+ @@recursive_level = level
15
+ end
16
+ def self.recursive_level
17
+ @@recursive_level
50
18
  end
51
19
 
52
- # get the hash value
53
- keys = group.gsub(/^\//,'').split('/')
54
- list_of_hosts = @@host_hash
55
- keys.each do |k|
56
- begin
57
- if list_of_hosts.key? k then
58
- list_of_hosts = list_of_hosts[k]
59
- else
60
- # if any part of the group name is not a key in the
61
- # host hash, then return the group.
62
- return [ group ]
20
+ def self.load_file(def_file=nil)
21
+ if def_file then
22
+ files = [ def_file ]
23
+ else
24
+ files = [ "/etc/pdo/pdo.yaml", "#{ENV['HOME']}/.pdo/pdo.yaml", ]
25
+ end
26
+
27
+ hosts = {}
28
+ files.each do |f|
29
+ begin
30
+ hosts.update(YAML::load_file(f))
31
+ rescue => ex
32
+ logger.warn { "#{ex.class}: #{ex.message}" }
33
+ logger.debug { ex.backtrace.join "\n" }
63
34
  end
64
- rescue => ex
65
- logger.warn {
66
- "failed to get hash value for #{group.inspect}. "\
67
- 'possibly an error in the yaml file.'
68
- }
69
- logger.debug { ex.backtrace.join "\n" }
70
- return []
71
35
  end
36
+ return @@host_hash = hosts
37
+
72
38
  end
39
+
40
+ def expand_group(group, level)
41
+ # given a group, recursively expand it into a list of hosts.
42
+ # if the group can't expand to a list of hosts, return that group.
43
+ # if there are exception expanding the group, return an empty list.
73
44
 
74
- # return empty array if the group is empty.
75
- return [] if list_of_hosts.nil?
45
+ hosts = []
76
46
 
77
- if list_of_hosts.is_a? Hash then
78
- list_of_hosts.keys.each do |key|
79
- hosts += expand_group("#{group}/#{key}".squeeze('/'), level)
47
+ level += 1
48
+ if level > @@recursive_level then
49
+ logger.warn "circle detected in the host definition file."
50
+ return []
80
51
  end
81
- elsif list_of_hosts.is_a? Array then
82
- list_of_hosts.each do |h|
83
- if not h.is_a? String then
52
+
53
+ # get the hash value
54
+ keys = group.gsub(/^\//,'').split('/')
55
+ list_of_hosts = @@host_hash
56
+ keys.each do |k|
57
+ begin
58
+ if list_of_hosts.key? k then
59
+ list_of_hosts = list_of_hosts[k]
60
+ else
61
+ # if any part of the group name is not a key in the
62
+ # host hash, then return the group.
63
+ return [ group ]
64
+ end
65
+ rescue => ex
84
66
  logger.warn {
85
- "invalid host or group format: #{h.inspect}\n"\
67
+ "failed to get hash value for #{group.inspect}. "\
86
68
  'possibly an error in the yaml file.'
87
69
  }
88
- next
70
+ logger.debug { ex.backtrace.join "\n" }
71
+ return []
72
+ end
73
+ end
74
+
75
+ # return empty array if the group is empty.
76
+ return [] if list_of_hosts.nil?
77
+
78
+ if list_of_hosts.is_a? Hash then
79
+ list_of_hosts.keys.each do |key|
80
+ hosts += expand_group("#{group}/#{key}".squeeze('/'), level)
89
81
  end
90
- if h.include? "/" then
91
- hosts += expand_group(h, level)
92
- else
93
- hosts << h
82
+ elsif list_of_hosts.is_a? Array then
83
+ list_of_hosts.each do |h|
84
+ if not h.is_a? String then
85
+ logger.warn {
86
+ "invalid host or group format: #{h.inspect}\n"\
87
+ 'possibly an error in the yaml file.'
88
+ }
89
+ next
90
+ end
91
+ if h.include? "/" then
92
+ hosts += expand_group(h, level)
93
+ else
94
+ hosts << h
95
+ end
94
96
  end
97
+ else
98
+ logger.fatal "I don't know how to handle this. "\
99
+ 'possibly an error in the yaml file.'
100
+ exit 1
95
101
  end
96
- else
97
- logger.fatal "I don't know how to handle this. "\
98
- 'possibly an error in the yaml file.'
99
- exit 1
102
+ return hosts
103
+
104
+ end # expand_group
105
+ private :expand_group
106
+
107
+ def get_hosts(group, step)
108
+ hosts = []
109
+ hosts += expand_group(group, 0)
110
+ hosts.uniq!
111
+ hosts = stepping hosts, step
112
+ return hosts
113
+
100
114
  end
101
- return hosts
102
-
103
- end # expand_group
104
- private :expand_group
105
115
 
106
- def get_hosts(group, step)
107
- hosts = []
108
- hosts += expand_group(group, 0)
109
- hosts.uniq!
110
- hosts = stepping hosts, step
111
- return hosts
112
-
113
- end
116
+ def stepping(hosts, step)
117
+ unless hosts.is_a? Array or step.is_a? Array then
118
+ logger.warn "both hosts or step should be array."
119
+ return nil
120
+ end
121
+
122
+ start, stride = step[0].to_i, step[1].to_i
123
+ # if stride > 0, stepping forward
124
+ # if stride < 0, stepping backward
125
+ # if stride == 0, no stepping
126
+ # if start or stride makes no sense, no stepping either
127
+ index = case
128
+ when stride > 0 then
129
+ (start-1...hosts.size).step(stride).to_a
130
+ when stride < 0 then
131
+ (-start+1..0).step(-stride).to_a.map {|x| -x}
132
+ else []
133
+ end
134
+
135
+ unless index.empty? then
136
+ alist = []
137
+ index.each do |i|
138
+ alist << hosts[i]
139
+ end
140
+ hosts = alist
141
+ end
114
142
 
115
- def stepping(hosts, step)
116
- unless hosts.is_a? Array or step.is_a? Array then
117
- logger.warn "both hosts or step should be array."
118
- return nil
143
+ return hosts
119
144
  end
120
-
121
- start, stride = step[0].to_i, step[1].to_i
122
- # if stride > 0, stepping forward
123
- # if stride < 0, stepping backward
124
- # if stride == 0, no stepping
125
- # if start or stride makes no sense, no stepping either
126
- index = case
127
- when stride > 0 then
128
- (start-1...hosts.size).step(stride).to_a
129
- when stride < 0 then
130
- (-start+1..0).step(-stride).to_a.map {|x| -x}
131
- else []
132
- end
133
-
134
- unless index.empty? then
135
- alist = []
136
- index.each do |i|
137
- alist << hosts[i]
138
- end
139
- hosts = alist
145
+
146
+ def show_hosts
147
+ pp @@host_hash
140
148
  end
141
149
 
142
- return hosts
143
- end
144
-
145
- def show_hosts
146
- pp @@host_hash
147
- end
148
-
149
- def get_sub_groups(group)
150
-
151
- keys = group.gsub(/^\//, '').split('/')
152
- pointer = @@host_hash
153
- keys.each do |k|
154
- begin
155
- if pointer.key? k then
156
- pointer = pointer[k]
157
- else
158
- # if any part of the given group name is not a key in the
159
- # host hash, then return an empty array.
160
- return [ ]
150
+ def get_sub_groups(group)
151
+
152
+ keys = group.gsub(/^\//, '').split('/')
153
+ pointer = @@host_hash
154
+ keys.each do |k|
155
+ begin
156
+ if pointer.key? k then
157
+ pointer = pointer[k]
158
+ else
159
+ # if any part of the given group name is not a key in the
160
+ # host hash, then return an empty array.
161
+ return [ ]
162
+ end
163
+ rescue => ex
164
+ logger.warn {
165
+ "failed to get hash value for #{group.inspect}. "\
166
+ 'maybe a wrong key is specifid?'
167
+ }
168
+ logger.debug { ex.backtrace.join "\n" }
169
+ return []
161
170
  end
162
- rescue => ex
163
- logger.warn {
164
- "failed to get hash value for #{group.inspect}. "\
165
- 'maybe a wrong key is specifid?'
166
- }
167
- logger.debug { ex.backtrace.join "\n" }
168
- return []
169
171
  end
170
- end
171
172
 
172
- # return empty array if the group is empty.
173
- return [] if pointer.nil?
174
-
175
- if pointer.is_a? Hash then
176
- return pointer.keys
177
- elsif pointer.is_a? Array then
178
- return pointer
179
- else
180
- logger.fatal "I don't know how to handle this. "\
181
- 'possibly an error in the yaml file.'
182
- exit 1
173
+ # return empty array if the group is empty.
174
+ return [] if pointer.nil?
175
+
176
+ if pointer.is_a? Hash then
177
+ return pointer.keys
178
+ elsif pointer.is_a? Array then
179
+ return pointer
180
+ else
181
+ logger.fatal "I don't know how to handle this. "\
182
+ 'possibly an error in the yaml file.'
183
+ exit 1
184
+ end
185
+
183
186
  end
184
-
185
- end
186
187
 
187
- end # module Host
188
+ end # module Host
189
+ end # module PDO
188
190
 
189
191
  # vim: set et ts=2 sts=2 sw=2 si sta :
@@ -4,28 +4,30 @@ require 'log4r'
4
4
  require 'log4r/yamlconfigurator'
5
5
  require 'log4r/outputter/datefileoutputter'
6
6
 
7
- module Logging
7
+ module PDO
8
+ module Logging
8
9
 
9
- include Log4r
10
- # set the default log directory
11
- Log4r::YamlConfigurator['LOGDIR'] =
12
- File.expand_path("#{File.dirname(__FILE__)}/../../log")
10
+ include Log4r
11
+ # set the default log directory
12
+ Log4r::YamlConfigurator['LOGDIR'] =
13
+ File.expand_path("#{File.dirname(__FILE__)}/../../log")
13
14
 
14
- def logger
15
+ def logger
15
16
 
16
- return @logger if @logger
17
+ return @logger if @logger
17
18
 
18
- conf_dir = File.expand_path("#{File.dirname(__FILE__)}/../../conf")
19
+ conf_dir = File.expand_path("#{File.dirname(__FILE__)}/../../conf")
19
20
 
20
- [conf_dir, '/etc/pdo', "#{ENV['HOME']}/.pdo"].each { |dir|
21
- conf = "#{dir}/log4r.yaml"
22
- Log4r::YamlConfigurator.load_yaml_file conf if File.exists? conf
23
- }
21
+ [conf_dir, '/etc/pdo', "#{ENV['HOME']}/.pdo"].each { |dir|
22
+ conf = "#{dir}/log4r.yaml"
23
+ Log4r::YamlConfigurator.load_yaml_file conf if File.exists? conf
24
+ }
24
25
 
25
- @logger = Logger[self.class.to_s] || Logger['pdo']
26
+ @logger = Logger[self.class.to_s] || Logger['pdo']
26
27
 
27
- end
28
+ end
28
29
 
29
- end # module Logging
30
+ end # module Logging
31
+ end # module PDO
30
32
 
31
33
  # vim: set et ts=2 sts=2 sw=2 si sta :
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ module PDO
6
+ class Opts
7
+ def self.parse(args, opts)
8
+ op = OptionParser.new
9
+ op.set_summary_width 15
10
+
11
+ op.banner = "pdo [opts]"
12
+ op.separator ""
13
+ op.separator "Specific options:"
14
+
15
+ op.on('-c CMD', 'the command to be executed',
16
+ "if CMD equals to '-', then read command from stdin") do |cmd|
17
+ if cmd == '-' then
18
+ opts.cmd = $stdin.read
19
+ else
20
+ opts.cmd = cmd
21
+ end
22
+ end
23
+
24
+ op.on('--count', 'count the number of hosts') do |count|
25
+ opts.count = true
26
+ end
27
+
28
+ op.on('--enum', 'enumerate the hosts') do |enum|
29
+ opts.enum = true
30
+ end
31
+
32
+ op.on('-f <name>',
33
+ 'name of the alternative host definition file') do |fn|
34
+ opts.host_definition_file = fn
35
+ end
36
+
37
+ op.on('-g <name1,name2,...>', Array,
38
+ 'comma separated group or host names') do |groups|
39
+ opts.groups = groups
40
+ end
41
+
42
+ op.on('-l', 'run the command CMD locally') do
43
+ opts.local = true
44
+ end
45
+
46
+ op.on('--step <m,n>', Array,
47
+ 'stepping the hosts, m and n must be integers;',
48
+ 'if n > 0, stepping forward; if n < 0 stepping',
49
+ 'backward') do |step|
50
+ opts.step = [step[0].to_i, step[1].to_i]
51
+ end
52
+
53
+ op.on('--sshopts <key1=val1,key2=val2,...>', Array,
54
+ 'ssh options as described in "man ssh_config"') do |sshopts|
55
+ opts.sshopts = {} unless opts.sshopts
56
+ sshopts.each do |opt|
57
+ key, val = opt.split '='
58
+ opts.sshopts[:"#{key}"] = val if key and val
59
+ end
60
+ end
61
+
62
+ op.on('-t INTEGER', Integer, 'number of threads') do |thread_num|
63
+ if thread_num < 0 then
64
+ raise ArgumentError,
65
+ "thread number must be greater or equal to zero"
66
+ end
67
+ opts.thread_num = thread_num
68
+ end
69
+
70
+ op.on('-x <name1,name2,...>', Array,
71
+ 'comma separated group or host names, which should be',
72
+ 'excluded from the final list') do |e_groups|
73
+ opts.e_groups = e_groups
74
+ end
75
+
76
+ op.on('-y', 'do not confirm, execute immediately') do
77
+ opts.confirm_before_execute = false
78
+ end
79
+
80
+ op.separator ""
81
+ op.separator "Common options:"
82
+
83
+ op.on_tail('-h', '--help', 'this help') do
84
+ puts op.help
85
+ exit 0
86
+ end
87
+
88
+ op.parse!(args)
89
+ return opts
90
+
91
+ end # self.parse()
92
+ end # class Opts
93
+ end # module PDO
94
+
95
+ # vim: set et ts=2 sts=2 sw=2 si sta :
@@ -2,102 +2,104 @@
2
2
 
3
3
  require_relative 'logging'
4
4
 
5
- class SSHCmd
6
- include Logging
5
+ module PDO
6
+ class SSHCmd
7
+ include Logging
7
8
 
8
- def initialize(local, sshopts)
9
+ def initialize(local, sshopts)
9
10
 
10
- @defaults = {
11
- :user => 'root',
12
- :port => '22',
13
- :ssh => '/usr/bin/ssh',
14
- :sshopts => {
15
- :ConnectTimeout => '60',
16
- :StrictHostKeyChecking => 'no',
17
- },
18
- }
19
- @local = local
20
- @sshopts = @defaults[:sshopts]
21
- @sshopts = @defaults[:sshopts].update sshopts if sshopts
22
- logger.debug { @sshopts.inspect }
23
- end
24
-
25
- def form(host, cmd)
26
- if host.match(/^(?:(\w+)@)?(\w+(?:\.\w+)*)(?::(\d+))?$/) then
27
- user, host, port = $1, $2, $3
11
+ @defaults = {
12
+ :user => 'root',
13
+ :port => '22',
14
+ :ssh => '/usr/bin/ssh',
15
+ :sshopts => {
16
+ :ConnectTimeout => '60',
17
+ :StrictHostKeyChecking => 'no',
18
+ },
19
+ }
20
+ @local = local
21
+ @sshopts = @defaults[:sshopts]
22
+ @sshopts = @defaults[:sshopts].update sshopts if sshopts
23
+ logger.debug { @sshopts.inspect }
28
24
  end
25
+
26
+ def form(host, cmd)
27
+ if host.match(/^(?:(\w+)@)?(\w+(?:\.\w+)*)(?::(\d+))?$/) then
28
+ user, host, port = $1, $2, $3
29
+ end
29
30
 
30
- cmd = cmd.dup # without dup, all tasks refer to the same
31
- cmd.strip!
32
- cmd.gsub! '_USER_', user ? user : @defaults[:user]
33
- cmd.gsub! '_HOST_', host
34
- cmd.gsub! '_PORT_', port ? port : @defaults[:port]
35
- # when opts.cmd == '-', the command is read from stdin.
36
- # in this case multiple lines can be entered. here I'm doing some
37
- # simple substitution for "\n".
38
- cmd.gsub! "\n", '; '
31
+ cmd = cmd.dup # without dup, all tasks refer to the same
32
+ cmd.strip!
33
+ cmd.gsub! '_USER_', user ? user : @defaults[:user]
34
+ cmd.gsub! '_HOST_', host
35
+ cmd.gsub! '_PORT_', port ? port : @defaults[:port]
36
+ # when opts.cmd == '-', the command is read from stdin.
37
+ # in this case multiple lines can be entered. here I'm doing some
38
+ # simple substitution for "\n".
39
+ cmd.gsub! "\n", '; '
39
40
 
40
- # escape "`$ characters in cmd, unless they're already escaped.
41
- if RUBY_VERSION.to_f < 1.9 then
42
- # v1.8 dose not support negative look-behind assertion, thus
43
- # doing it in 2 steps.
44
- if cmd.match /["`$]/ then
45
- if not cmd.match /['\\]["`$]/ then
46
- cmd.gsub! /(["`$])/, '\\\\\1'
41
+ # escape "`$ characters in cmd, unless they're already escaped.
42
+ if RUBY_VERSION.to_f < 1.9 then
43
+ # v1.8 dose not support negative look-behind assertion, thus
44
+ # doing it in 2 steps.
45
+ if cmd.match /["`$]/ then
46
+ if not cmd.match /['\\]["`$]/ then
47
+ cmd.gsub! /(["`$])/, '\\\\\1'
48
+ end
47
49
  end
50
+ else
51
+ cmd.gsub! /(?<!['\\])(["`$])/, '\\\\\1'
48
52
  end
49
- else
50
- cmd.gsub! /(?<!['\\])(["`$])/, '\\\\\1'
51
- end
52
53
 
53
- if @local then
54
- return cmd
55
- else
56
- ssh = @defaults[:ssh]
57
- ssh = [ ssh, '-l', "#{user}"].join ' ' if user
58
- ssh = [ ssh, '-p', "#{port}"].join ' ' if port
59
- @sshopts.each do |k, v|
60
- ssh = [ssh, '-o', "#{k}=#{v}"].join ' '
54
+ if @local then
55
+ return cmd
56
+ else
57
+ ssh = @defaults[:ssh]
58
+ ssh = [ ssh, '-l', "#{user}"].join ' ' if user
59
+ ssh = [ ssh, '-p', "#{port}"].join ' ' if port
60
+ @sshopts.each do |k, v|
61
+ ssh = [ssh, '-o', "#{k}=#{v}"].join ' '
62
+ end
63
+ ssh = [ ssh, "#{host}", "\"#{cmd}\""].join ' '
64
+ return ssh
61
65
  end
62
- ssh = [ ssh, "#{host}", "\"#{cmd}\""].join ' '
63
- return ssh
64
66
  end
65
67
  end
66
- end
67
68
 
68
- class Task
69
- include Logging
69
+ class Task
70
+ include Logging
70
71
 
71
- def initialize
72
- @task_q = Queue.new
73
- end
72
+ def initialize
73
+ @task_q = Queue.new
74
+ end
74
75
 
75
- def add(task)
76
- @task_q << task
77
- end
76
+ def add(task)
77
+ @task_q << task
78
+ end
78
79
 
79
- def next
80
- begin
81
- @task_q.deq(non_block=true)
82
- rescue ThreadError
83
- nil
80
+ def next
81
+ begin
82
+ @task_q.deq(non_block=true)
83
+ rescue ThreadError
84
+ nil
85
+ end
84
86
  end
85
- end
86
87
 
87
- def size
88
- @task_q.length
89
- end
88
+ def size
89
+ @task_q.length
90
+ end
90
91
 
91
- def print_all
92
- tmp_q = Queue.new
93
- while not @task_q.empty? do
94
- task = @task_q.deq
95
- printf "%s\n", task
96
- tmp_q << task
92
+ def print_all
93
+ tmp_q = Queue.new
94
+ while not @task_q.empty? do
95
+ task = @task_q.deq
96
+ printf "%s\n", task
97
+ tmp_q << task
98
+ end
99
+ @task_q = tmp_q
97
100
  end
98
- @task_q = tmp_q
99
- end
100
101
 
101
- end
102
+ end # class SSHCmd
103
+ end # module PDO
102
104
 
103
105
  # vim: set et ts=2 sts=2 sw=2 si sta :
@@ -1,3 +1,3 @@
1
- module Pdo
2
- VERSION = "0.0.3"
1
+ module PDO
2
+ VERSION = "0.0.5"
3
3
  end
@@ -6,7 +6,7 @@ require 'pdo/version'
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = 'pdo'
8
8
  gem.license = 'MIT'
9
- gem.version = Pdo::VERSION
9
+ gem.version = PDO::VERSION
10
10
  gem.authors = ['bqbn']
11
11
  gem.email = ['bqbn@openken.com']
12
12
  gem.description = 'pdo is a wrapper for running commands on or '\
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-20 00:00:00.000000000 Z
12
+ date: 2013-10-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: log4r
@@ -47,7 +47,7 @@ files:
47
47
  - lib/pdo.rb
48
48
  - lib/pdo/host.rb
49
49
  - lib/pdo/logging.rb
50
- - lib/pdo/pdoopts.rb
50
+ - lib/pdo/opts.rb
51
51
  - lib/pdo/task.rb
52
52
  - lib/pdo/version.rb
53
53
  - log/.gitignore
@@ -1,94 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'optparse'
4
-
5
- class PdoOpts
6
- def self.parse(args, opts)
7
- op = OptionParser.new
8
- op.set_summary_width 15
9
-
10
- op.banner = "pdo [opts]"
11
- op.separator ""
12
- op.separator "Specific options:"
13
-
14
- op.on('-c CMD', 'the command to be executed',
15
- "if CMD equals to '-', then read command from stdin") do |cmd|
16
- if cmd == '-' then
17
- opts.cmd = $stdin.read
18
- else
19
- opts.cmd = cmd
20
- end
21
- end
22
-
23
- op.on('--count', 'count the number of hosts') do |count|
24
- opts.count = true
25
- end
26
-
27
- op.on('--enum', 'enumerate the hosts') do |enum|
28
- opts.enum = true
29
- end
30
-
31
- op.on('-f <name>',
32
- 'name of the alternative host definition file') do |fn|
33
- opts.host_definition_file = fn
34
- end
35
-
36
- op.on('-g <name1,name2,...>', Array,
37
- 'comma separated group or host names') do |groups|
38
- opts.groups = groups
39
- end
40
-
41
- op.on('-l', 'run the command CMD locally') do
42
- opts.local = true
43
- end
44
-
45
- op.on('--step <m,n>', Array,
46
- 'stepping the hosts, m and n must be integers;',
47
- 'if n > 0, stepping forward; if n < 0 stepping',
48
- 'backward') do |step|
49
- opts.step = [step[0].to_i, step[1].to_i]
50
- end
51
-
52
- op.on('--sshopts <key1=val1,key2=val2,...>', Array,
53
- 'ssh options as described in "man ssh_config"') do |sshopts|
54
- opts.sshopts = {} unless opts.sshopts
55
- sshopts.each do |opt|
56
- key, val = opt.split '='
57
- opts.sshopts[:"#{key}"] = val if key and val
58
- end
59
- end
60
-
61
- op.on('-t INTEGER', Integer, 'number of threads') do |thread_num|
62
- if thread_num < 0 then
63
- raise ArgumentError,
64
- "thread number must be greater or equal to zero"
65
- end
66
- opts.thread_num = thread_num
67
- end
68
-
69
- op.on('-x <name1,name2,...>', Array,
70
- 'comma separated group or host names, which should be',
71
- 'excluded from the final list') do |e_groups|
72
- opts.e_groups = e_groups
73
- end
74
-
75
- op.on('-y', 'do not confirm, execute immediately') do
76
- opts.confirm_before_execute = false
77
- end
78
-
79
- op.separator ""
80
- op.separator "Common options:"
81
-
82
- op.on_tail('-h', '--help', 'this help') do
83
- puts op.help
84
- exit 0
85
- end
86
-
87
- op.parse!(args)
88
- return opts
89
-
90
- end # self.parse()
91
-
92
- end
93
-
94
- # vim: set et ts=2 sts=2 sw=2 si sta :