mybot 0.1.1 → 0.2.0
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/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
|