mybot 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -2
- data/README.md +83 -132
- data/lib/mybot.rb +18 -25
- data/lib/mybot/base.rb +7 -10
- data/lib/mybot/cli.rb +15 -19
- data/lib/mybot/command.rb +66 -53
- data/lib/mybot/fmt.rb +28 -151
- data/lib/mybot/helpers.rb +8 -6
- data/lib/mybot/node.rb +40 -85
- data/lib/mybot/nodes.rb +1 -10
- data/lib/mybot/recipes.rb +26 -0
- data/lib/mybot/tasks.rb +13 -9
- data/lib/mybot/templates.rb +1 -4
- data/lib/mybot/version.rb +1 -1
- data/mybot.gemspec +6 -6
- metadata +13 -38
- data/Botfile +0 -12
- data/CHANGELOG.md +0 -2
- data/lib/mybot/installer.rb +0 -31
- data/lib/mybot/lib.rb +0 -31
- data/lib/mybot/libs.rb +0 -44
- data/lib/mybot/loader.rb +0 -25
- data/vendor/lib/.gitkeep +0 -0
- data/vendor/plugins/.gitkeep +0 -0
- data/vendor/tasks/.gitkeep +0 -0
- data/vendor/tpl/.gitkeep +0 -0
data/lib/mybot/fmt.rb
CHANGED
@@ -2,174 +2,51 @@ require "colored"
|
|
2
2
|
|
3
3
|
module Mybot
|
4
4
|
module Fmt
|
5
|
-
|
6
|
-
info_format = "INFO"
|
7
|
-
info_format = info_format.blue.bold if $USE_COLOR
|
8
|
-
puts "#{info_format} #{msg}"
|
9
|
-
end
|
5
|
+
WIDTH = 10
|
10
6
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
def print_cmd(type, msg, *colors)
|
8
|
+
if $MYBOT_SHOW_CMD
|
9
|
+
$stdout.print "#{spaces(type)}#{colored(type, *colors)} #{msg.to_s}"
|
10
|
+
end
|
15
11
|
end
|
16
12
|
|
17
|
-
def
|
18
|
-
|
19
|
-
error_format = error_format.red.bold if $USE_COLOR
|
20
|
-
puts "#{error_format} #{msg}"
|
21
|
-
abort
|
13
|
+
def print_cmd!(type, msg, *colors)
|
14
|
+
print_cmd type, "#{msg}\n", *colors
|
22
15
|
end
|
23
16
|
|
24
|
-
def
|
25
|
-
|
26
|
-
task_format = task_format.green.bold if $USE_COLOR
|
27
|
-
puts "#{task_format} #{task}"
|
17
|
+
def print_stdout(data, force = false)
|
18
|
+
$stdout.print colored(data, :green) if $MYBOT_SHOW_OUTPUT || force
|
28
19
|
end
|
29
20
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
primary_cmd "RUN", cmd, options
|
34
|
-
secondary_cmd "SUDO" if options[:sudo]
|
35
|
-
secondary_cmd "CWD", options[:cwd] if options[:cwd] != ""
|
36
|
-
|
37
|
-
unless options[:env].empty?
|
38
|
-
secondary_cmd "ENV"
|
39
|
-
kv_cmd options[:env]
|
40
|
-
end
|
21
|
+
def print_stderr(data, force = false)
|
22
|
+
$stdout.print colored(data, :red) if $MYBOT_SHOW_OUTPUT || force
|
41
23
|
end
|
42
24
|
|
43
|
-
def
|
44
|
-
if $
|
45
|
-
|
46
|
-
|
25
|
+
def print_progress(n)
|
26
|
+
if $MYBOT_SHOW_CMD
|
27
|
+
cmd = colored "progress", :blue, :bold
|
28
|
+
$stdout.print "\r#{spaces('progress')}#{cmd} #{n}%"
|
29
|
+
puts if n == 100
|
47
30
|
end
|
48
|
-
|
49
|
-
secondary_cmd "HANDLE", s
|
50
31
|
end
|
51
|
-
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
lf_format = lf_format.bold if $USE_COLOR
|
57
|
-
|
58
|
-
if options[:shadow]
|
59
|
-
data = "*" * data.size
|
60
|
-
end
|
61
|
-
|
62
|
-
secondary_cmd "WRITE", "#{data}#{lf_format}"
|
63
|
-
end
|
64
|
-
|
65
|
-
def status_info(result)
|
66
|
-
return unless $SHOW_CMD
|
67
|
-
|
68
|
-
value_format = "#{result[:exit_status]}"
|
69
|
-
|
70
|
-
if $USE_COLOR
|
71
|
-
if result[:exit_status] == 0
|
72
|
-
value_format = value_format.green.bold
|
73
|
-
else
|
74
|
-
value_format = value_format.red.bold
|
32
|
+
|
33
|
+
def colored(str, *colors)
|
34
|
+
if $MYBOT_USE_COLORS
|
35
|
+
colors.each do |c|
|
36
|
+
str = str.send(c)
|
75
37
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
time_info result[:time]
|
80
|
-
|
81
|
-
if result[:exit_status] != 0
|
82
|
-
stdout(result[:stdout])
|
83
|
-
stderr(result[:stderr])
|
38
|
+
str
|
39
|
+
else
|
40
|
+
str
|
84
41
|
end
|
85
42
|
end
|
86
43
|
|
87
|
-
def
|
88
|
-
|
89
|
-
|
90
|
-
stdout_data_format = data.split("\r\n").join("\n")
|
91
|
-
stdout_data_format = stdout_data_format.green if $USE_COLOR
|
92
|
-
|
93
|
-
secondary_cmd "STDOUT"
|
94
|
-
puts stdout_data_format
|
44
|
+
def spaces(str)
|
45
|
+
" " * (WIDTH - str.size)
|
95
46
|
end
|
96
47
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
stderr_data_format = data
|
101
|
-
stderr_data_format = stderr_data_format.red if $USE_COLOR
|
102
|
-
|
103
|
-
secondary_cmd "STDERR"
|
104
|
-
puts stderr_data_format
|
105
|
-
end
|
106
|
-
|
107
|
-
def stdout_live(data)
|
108
|
-
return unless $LIVE_STDOUT
|
109
|
-
|
110
|
-
stdout_data_format = data
|
111
|
-
stdout_data_format = stdout_data_format.green if $USE_COLOR
|
112
|
-
|
113
|
-
$stdout.print stdout_data_format
|
114
|
-
end
|
115
|
-
|
116
|
-
def stderr_live(data)
|
117
|
-
return unless $LIVE_STDERR
|
118
|
-
|
119
|
-
stderr_data_format = data
|
120
|
-
stderr_data_format = stderr_data_format.red if $USE_COLOR
|
121
|
-
|
122
|
-
$stdout.print stderr_data_format
|
123
|
-
end
|
124
|
-
|
125
|
-
def upload_info(options)
|
126
|
-
return unless $SHOW_CMD
|
127
|
-
|
128
|
-
primary_cmd "UPLOAD", options[:file], options
|
129
|
-
secondary_cmd "TO", options[:to]
|
130
|
-
end
|
131
|
-
|
132
|
-
def download_info(options)
|
133
|
-
return unless $SHOW_CMD
|
134
|
-
|
135
|
-
primary_cmd "DOWNLOAD", options[:file], options
|
136
|
-
secondary_cmd "TO", options[:to]
|
137
|
-
end
|
138
|
-
|
139
|
-
def prompt(user, host)
|
140
|
-
prompt_format = "[#{user}@#{host}]"
|
141
|
-
prompt_format = prompt_format.white if $USE_COLOR
|
142
|
-
end
|
143
|
-
|
144
|
-
def progress(n)
|
145
|
-
return unless $SHOW_CMD
|
146
|
-
|
147
|
-
progress_format = "PROGRESS"
|
148
|
-
progress_format = progress_format.blue.bold if $USE_COLOR
|
149
|
-
|
150
|
-
$stdout.print "\r #{progress_format} #{n}%"
|
151
|
-
puts if n == 100
|
152
|
-
end
|
153
|
-
|
154
|
-
def time_info(time)
|
155
|
-
secondary_cmd "TIME", "#{time}s"
|
156
|
-
end
|
157
|
-
|
158
|
-
def primary_cmd(name, value, options = {})
|
159
|
-
name = name.bold if $USE_COLOR
|
160
|
-
prompt_format = prompt(options[:user], options[:host])
|
161
|
-
puts "#{prompt_format} #{name} #{value}"
|
162
|
-
end
|
163
|
-
|
164
|
-
def secondary_cmd(name, value = "")
|
165
|
-
name = name.blue.bold if $USE_COLOR
|
166
|
-
puts " #{name} #{value}"
|
167
|
-
end
|
168
|
-
|
169
|
-
def kv_cmd(options)
|
170
|
-
options.each do |k, v|
|
171
|
-
puts " #{k}: #{v}"
|
172
|
-
end
|
48
|
+
def asterisks(str)
|
49
|
+
"*" * str.size
|
173
50
|
end
|
174
51
|
end
|
175
52
|
end
|
data/lib/mybot/helpers.rb
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
module Mybot
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Helpers
|
3
|
+
include Fmt
|
4
|
+
|
5
|
+
def wait(msg = "Press any key to continue...")
|
6
|
+
print_cmd "wait", msg, :blue, :bold
|
5
7
|
$stdin.gets
|
6
8
|
end
|
7
9
|
|
8
10
|
def ask(q = "")
|
9
|
-
|
11
|
+
print_cmd "ask", q, :blue, :bold
|
10
12
|
$stdin.gets.chomp
|
11
13
|
end
|
12
14
|
|
13
15
|
def yes?(q = "")
|
14
16
|
result = ""
|
15
17
|
loop do
|
16
|
-
|
18
|
+
print_cmd "ask", q, :blue, :bold
|
17
19
|
result = $stdin.gets.chomp
|
18
20
|
break if result =~ /y|yes|Y|YES|Yes|n|no|N|NO|No/
|
19
21
|
end
|
20
22
|
|
21
23
|
result =~ /y|yes|Y|YES|Yes/
|
22
24
|
end
|
23
|
-
|
25
|
+
end
|
24
26
|
end
|
data/lib/mybot/node.rb
CHANGED
@@ -5,158 +5,113 @@ module Mybot
|
|
5
5
|
class Node
|
6
6
|
include Fmt
|
7
7
|
|
8
|
-
attr_accessor :host, :user, :options
|
9
|
-
|
10
8
|
def initialize(host, user, options = {})
|
11
9
|
@host, @user, @options = host, user, options
|
12
10
|
end
|
13
11
|
|
14
|
-
def
|
15
|
-
@ssh ||= Net::SSH.start @host, @user, @options
|
16
|
-
end
|
17
|
-
|
18
|
-
def sftp
|
19
|
-
@sftp ||= Net::SFTP.start @host, @user, @options
|
20
|
-
end
|
21
|
-
|
22
|
-
def run(cmd, options = {}, &block)
|
23
|
-
error "cmd cannot be empty" if cmd == ""
|
24
|
-
|
25
|
-
start_time = Time.now
|
26
|
-
options[:sudo] ||= false
|
27
|
-
options[:cwd] ||= ""
|
28
|
-
options[:env] ||= {}
|
29
|
-
|
12
|
+
def run(cmd, options = {})
|
30
13
|
command = Command.new
|
31
14
|
yield command if block_given?
|
32
15
|
|
33
|
-
ssh.open_channel do |ch
|
16
|
+
ssh.open_channel do |ch|
|
34
17
|
ch.request_pty do |ch, ok|
|
35
|
-
|
18
|
+
abort "cannot request pty" unless ok
|
36
19
|
end
|
37
20
|
|
38
21
|
command.channel = ch
|
39
22
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
:sudo => options[:sudo],
|
44
|
-
:cwd => options[:cwd],
|
45
|
-
:env => options[:env]
|
46
|
-
}
|
47
|
-
|
48
|
-
if options[:sudo]
|
49
|
-
cmd = "sudo #{cmd}"
|
50
|
-
handle_sudo(command)
|
51
|
-
end
|
23
|
+
options[:env] ||= {}
|
24
|
+
options[:sudo] ||= false
|
25
|
+
options[:cwd] ||= ""
|
52
26
|
|
53
27
|
unless options[:env].empty?
|
54
|
-
values = options[:env].map { |k, v| "#{k}
|
28
|
+
values = options[:env].map { |k, v| "#{k}='#{v}'" }.join " "
|
55
29
|
cmd = "#{values} #{cmd}"
|
56
30
|
end
|
57
31
|
|
32
|
+
if options[:sudo]
|
33
|
+
cmd = "sudo #{cmd}"
|
34
|
+
end
|
35
|
+
|
58
36
|
if options[:cwd] != ""
|
59
37
|
cmd = "cd #{options[:cwd]} && #{cmd}"
|
60
38
|
end
|
61
39
|
|
40
|
+
print_cmd! "run", cmd, :green, :bold
|
41
|
+
|
62
42
|
ch.exec cmd do |ch, ok|
|
63
|
-
|
43
|
+
abort "cannot exec command" unless ok
|
64
44
|
|
65
45
|
ch.on_data do |ch, data|
|
66
46
|
command.handle_stdout data
|
67
47
|
end
|
68
48
|
|
69
|
-
ch.on_extended_data do |ch, data|
|
70
|
-
command.handle_stderr data
|
49
|
+
ch.on_extended_data do |ch, type, data|
|
50
|
+
command.handle_stderr data if type == 1
|
71
51
|
end
|
72
52
|
|
73
53
|
ch.on_request("exit-status") do |ch, data|
|
74
|
-
command.
|
54
|
+
command.exit = data.read_long
|
75
55
|
end
|
76
56
|
|
77
57
|
ch.on_close do |ch|
|
78
|
-
command.time = Time.now - start_time
|
79
58
|
command.handle_close
|
80
59
|
end
|
81
60
|
end
|
82
61
|
end
|
83
62
|
|
84
63
|
ssh.loop
|
85
|
-
|
86
64
|
return command.result
|
87
65
|
end
|
88
66
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
:user => @user,
|
97
|
-
:file => file,
|
98
|
-
:to => options[:to]
|
99
|
-
})
|
67
|
+
def exists?(file)
|
68
|
+
sftp.stat!(file) do |resp|
|
69
|
+
return resp.ok?
|
70
|
+
end
|
71
|
+
rescue Net::SFTP::StatusException
|
72
|
+
false
|
73
|
+
end
|
100
74
|
|
101
|
-
|
75
|
+
def upload(from, to, options = {})
|
76
|
+
print_cmd! "upload", "#{from} -> #{to}", :green, :bold
|
77
|
+
sftp.upload!(from, to) do |event, uploader, *args|
|
102
78
|
case event
|
103
79
|
when :put
|
104
80
|
n = (args[1].to_f * 100 / args[0].size.to_f).to_i
|
105
|
-
|
81
|
+
print_progress(n)
|
106
82
|
when :finish
|
107
|
-
|
83
|
+
print_progress(100)
|
108
84
|
end
|
109
85
|
end
|
110
|
-
|
111
|
-
time_info Time.now - start_time
|
112
86
|
end
|
113
87
|
|
114
|
-
def download(
|
115
|
-
|
116
|
-
|
117
|
-
start_time = Time.now
|
118
|
-
download_info({
|
119
|
-
:host => @host,
|
120
|
-
:user => @user,
|
121
|
-
:file => file,
|
122
|
-
:to => options[:to]
|
123
|
-
})
|
124
|
-
|
125
|
-
sftp.download!(file, options[:to]) do |event, uploader, *args|
|
88
|
+
def download(from, to, options = {})
|
89
|
+
print_cmd! "download", "#{from} -> #{to}", :green, :bold
|
90
|
+
sftp.download!(from, to) do |event, uploader, *args|
|
126
91
|
case event
|
127
92
|
when :get
|
128
93
|
size = 0
|
129
94
|
if args[0].size
|
130
95
|
size = args[0].size
|
131
96
|
else
|
132
|
-
size = sftp.stat!(
|
97
|
+
size = sftp.stat!(from).size
|
133
98
|
end
|
134
99
|
n = (args[1].to_f * 100 / size.to_f).to_i
|
135
|
-
|
100
|
+
print_progress(n)
|
136
101
|
when :finish
|
137
|
-
|
102
|
+
print_progress(100)
|
138
103
|
end
|
139
104
|
end
|
140
|
-
|
141
|
-
time_info Time.now - start_time
|
142
105
|
end
|
143
106
|
|
144
107
|
private
|
145
108
|
|
146
|
-
def
|
147
|
-
@
|
148
|
-
|
149
|
-
command.on "[sudo] password" do
|
150
|
-
command.write @options[:password], :shadow => true
|
151
|
-
end
|
152
|
-
|
153
|
-
command.on "Password:" do
|
154
|
-
command.write @options[:password], :shadow => true
|
155
|
-
end
|
109
|
+
def ssh
|
110
|
+
@ssh ||= Net::SSH.start @host, @user, @options
|
111
|
+
end
|
156
112
|
|
157
|
-
|
158
|
-
|
159
|
-
end
|
113
|
+
def sftp
|
114
|
+
@sftp ||= Net::SFTP.start @host, @user, @options
|
160
115
|
end
|
161
116
|
end
|
162
117
|
end
|
data/lib/mybot/nodes.rb
CHANGED
@@ -3,14 +3,5 @@ module Mybot
|
|
3
3
|
def node(host, user, options = {})
|
4
4
|
Node.new host, user, options
|
5
5
|
end
|
6
|
-
|
7
|
-
def run(*args, &block)
|
8
|
-
@nodes ||= []
|
9
|
-
error "no node specified" if @nodes.empty?
|
10
|
-
|
11
|
-
@nodes.each do |node|
|
12
|
-
node.run(*args, &block)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
6
|
+
end
|
16
7
|
end
|