mybot 0.0.2 → 0.0.3
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/Botfile +10 -0
- data/CHANGELOG.md +18 -0
- data/lib/mybot.rb +6 -0
- data/lib/mybot/aws.rb +54 -0
- data/lib/mybot/command.rb +15 -19
- data/lib/mybot/commands.rb +24 -0
- data/lib/mybot/core-ext/array.rb +9 -0
- data/lib/mybot/core-ext/class.rb +53 -0
- data/lib/mybot/fmt.rb +23 -22
- data/lib/mybot/lib.rb +68 -7
- data/lib/mybot/libs.rb +41 -0
- data/lib/mybot/messages.rb +8 -4
- data/lib/mybot/node.rb +44 -53
- data/lib/mybot/recipes.rb +2 -2
- data/lib/mybot/result.rb +26 -0
- data/lib/mybot/utils.rb +7 -0
- data/lib/mybot/version.rb +1 -1
- data/mybot.gemspec +1 -0
- data/vendor/lib/core/fs.rb +15 -9
- data/vendor/lib/core/osx/rails.rb +31 -0
- data/vendor/lib/core/osx/static.rb +31 -0
- data/vendor/lib/core/ubuntu/apt.rb +19 -2
- data/vendor/lib/core/ubuntu/git.rb +12 -0
- data/vendor/lib/core/ubuntu/mysql.rb +131 -0
- data/vendor/lib/core/ubuntu/nginx.rb +43 -0
- data/vendor/lib/core/ubuntu/php.rb +76 -0
- data/vendor/lib/core/ubuntu/rails.rb +105 -0
- data/vendor/lib/core/ubuntu/ruby.rb +4 -3
- data/vendor/lib/core/ubuntu/static.rb +50 -0
- data/vendor/lib/core/ubuntu/users.rb +1 -1
- data/vendor/tpl/core/ubuntu/nginx/nginx.conf.erb +72 -0
- data/vendor/tpl/core/ubuntu/php/php.ini.erb +1818 -0
- metadata +32 -2
data/lib/mybot/libs.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Mybot
|
2
|
+
module Libs
|
3
|
+
def use(lib)
|
4
|
+
if lib.is_a?(Array)
|
5
|
+
lib.each do |l|
|
6
|
+
_use(l)
|
7
|
+
end
|
8
|
+
else
|
9
|
+
_use(lib)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def _use(lib)
|
14
|
+
lib_name = lib.split("/").last
|
15
|
+
lib_file = File.join(LIB_PATH, "#{lib}.rb")
|
16
|
+
|
17
|
+
unless File.exists?(lib_file)
|
18
|
+
error "cannot load lib '#{lib_file}'"
|
19
|
+
end
|
20
|
+
|
21
|
+
require lib_file
|
22
|
+
const = lib.split("/").map { |x| x.capitalize }.join("::")
|
23
|
+
klass = Kernel.qualified_const_get(const)
|
24
|
+
|
25
|
+
if klass.instance_method(:initialize).arity == 1
|
26
|
+
@libs[lib_name.to_sym] ||= klass.new(self)
|
27
|
+
else
|
28
|
+
warning "#{lib_name.capitalize} library constructor should " +
|
29
|
+
"take one argument"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_missing(name, *args, &block)
|
34
|
+
if @libs[name.to_sym]
|
35
|
+
@libs[name.to_sym]
|
36
|
+
else
|
37
|
+
error "no such library loaded: #{name}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/mybot/messages.rb
CHANGED
@@ -3,23 +3,27 @@ require "colored"
|
|
3
3
|
module Mybot
|
4
4
|
module Messages
|
5
5
|
def info(msg)
|
6
|
-
info_format = "INFO"
|
6
|
+
info_format = "INFO"
|
7
|
+
info_format = info_format.blue.bold if Fmt.use_color
|
7
8
|
puts "#{info_format} #{msg}"
|
8
9
|
end
|
9
10
|
|
10
11
|
def warning(msg)
|
11
|
-
warning_format = "WARNING"
|
12
|
+
warning_format = "WARNING"
|
13
|
+
warning_format = warning_format.magenta.bold if Fmt.use_color
|
12
14
|
puts "#{warning_format} #{msg}"
|
13
15
|
end
|
14
16
|
|
15
17
|
def error(msg)
|
16
|
-
error_format = "ERROR"
|
18
|
+
error_format = "ERROR"
|
19
|
+
error_format = error_format.red.bold if Fmt.use_color
|
17
20
|
puts "#{error_format} #{msg}"
|
18
21
|
abort
|
19
22
|
end
|
20
23
|
|
21
24
|
def task_info(name)
|
22
|
-
task_format = "TASK"
|
25
|
+
task_format = "TASK"
|
26
|
+
task_format = task_format.green.bold if Fmt.use_color
|
23
27
|
puts "#{task_format} #{name}"
|
24
28
|
end
|
25
29
|
end
|
data/lib/mybot/node.rb
CHANGED
@@ -4,6 +4,8 @@ require "net/sftp"
|
|
4
4
|
module Mybot
|
5
5
|
class Node
|
6
6
|
include Messages
|
7
|
+
include Libs
|
8
|
+
|
7
9
|
attr_accessor :host, :user, :options, :ssh, :sftp, :fmt
|
8
10
|
|
9
11
|
def initialize(host, user, options = {})
|
@@ -20,50 +22,12 @@ module Mybot
|
|
20
22
|
@sftp ||= Net::SFTP.start(@host, @user, @options)
|
21
23
|
end
|
22
24
|
|
23
|
-
def use(lib)
|
24
|
-
if lib.is_a?(Array)
|
25
|
-
lib.each do |l|
|
26
|
-
_use(l)
|
27
|
-
end
|
28
|
-
else
|
29
|
-
_use(lib)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def _use(lib)
|
34
|
-
lib_name = lib.split("/").last
|
35
|
-
lib_file = File.join(LIB_PATH, "#{lib}.rb")
|
36
|
-
|
37
|
-
unless File.exists?(lib_file)
|
38
|
-
error "cannot load lib '#{lib_file}'"
|
39
|
-
end
|
40
|
-
|
41
|
-
require lib_file
|
42
|
-
const = lib.split("/").map { |x| x.capitalize }.join("::")
|
43
|
-
klass = Kernel.qualified_const_get(const)
|
44
|
-
|
45
|
-
if klass.instance_method(:initialize).arity == 1
|
46
|
-
@libs[lib_name.to_sym] ||= klass.new(self)
|
47
|
-
else
|
48
|
-
warning "#{lib_name.capitalize} library constructor should " +
|
49
|
-
"take one argument"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def method_missing(name, *args, &block)
|
54
|
-
if @libs[name.to_sym]
|
55
|
-
@libs[name.to_sym]
|
56
|
-
else
|
57
|
-
error "no such library loaded: #{name}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
25
|
def run(options, &block)
|
62
26
|
error "cmd not specified" unless options[:cmd]
|
63
27
|
|
64
28
|
command = Command.new(self)
|
65
29
|
yield command if block_given?
|
66
|
-
|
30
|
+
|
67
31
|
ssh.open_channel do |ch|
|
68
32
|
ch.request_pty do |ch, ok|
|
69
33
|
@fmt.error "cannot request pty" unless ok
|
@@ -71,27 +35,20 @@ module Mybot
|
|
71
35
|
|
72
36
|
command.channel = ch
|
73
37
|
|
74
|
-
|
75
|
-
env = []
|
76
|
-
options[:env].each do |k, v|
|
77
|
-
env << "#{k}='#{v}'"
|
78
|
-
end
|
79
|
-
options[:cmd] = "#{env.join(" ")} #{options[:cmd]}"
|
80
|
-
end
|
38
|
+
inject_env(options)
|
81
39
|
|
82
40
|
if options[:sudo]
|
83
41
|
options[:cmd] = "sudo #{options[:cmd]}"
|
84
42
|
command.handle_sudo
|
85
43
|
end
|
86
44
|
|
87
|
-
|
88
|
-
|
89
|
-
end
|
45
|
+
prepend_cwd(options)
|
46
|
+
prepend_sources(options)
|
90
47
|
|
91
48
|
@fmt.run(options[:cmd])
|
92
49
|
|
93
50
|
ch.exec options[:cmd] do |ch, ok|
|
94
|
-
@fmt.error "
|
51
|
+
@fmt.error "cannot exec #{options[:cmd]}" unless ok
|
95
52
|
|
96
53
|
ch.on_data do |ch, data|
|
97
54
|
command.handle_stdout(data)
|
@@ -102,17 +59,51 @@ module Mybot
|
|
102
59
|
end
|
103
60
|
|
104
61
|
ch.on_request("exit-status") do |ch, data|
|
105
|
-
command.exit_status = data.read_long
|
62
|
+
command.result.exit_status = data.read_long
|
106
63
|
end
|
107
64
|
|
108
65
|
ch.on_close do |ch|
|
109
|
-
|
66
|
+
#
|
110
67
|
end
|
111
68
|
end
|
112
69
|
end
|
113
70
|
|
114
71
|
ssh.loop
|
115
|
-
return command.
|
72
|
+
return command.result
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def inject_env(options)
|
78
|
+
if options[:env]
|
79
|
+
env = []
|
80
|
+
options[:env].each do |k, v|
|
81
|
+
env << "#{k}='#{v}'"
|
82
|
+
end
|
83
|
+
options[:cmd] = "#{env.join(" ")} #{options[:cmd]}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def prepend_cwd(options)
|
88
|
+
if options[:cwd]
|
89
|
+
options[:cmd] = "cd #{options[:cwd]} && #{options[:cmd]}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def prepend_sources(options)
|
94
|
+
sources = [
|
95
|
+
File.join("~", ".bashrc"),
|
96
|
+
File.join("~", ".bash_profile"),
|
97
|
+
File.join("~", ".profile")
|
98
|
+
].map { |f| File.expand_path(f) }
|
99
|
+
|
100
|
+
sources.reject! { |f| !File.exists?(f) }
|
101
|
+
|
102
|
+
prefix = sources.map do |s|
|
103
|
+
"source #{File.expand_path(s)}"
|
104
|
+
end.join(" && ")
|
105
|
+
|
106
|
+
options[:cmd] = "#{prefix} && #{options[:cmd]}"
|
116
107
|
end
|
117
108
|
end
|
118
109
|
end
|
data/lib/mybot/recipes.rb
CHANGED
@@ -4,10 +4,10 @@ module Mybot
|
|
4
4
|
|
5
5
|
def recipes
|
6
6
|
@recipes ||= (
|
7
|
+
Dir["Botfile"] +
|
7
8
|
Dir[File.join(GEM_PATH, "Botfile")] +
|
8
9
|
Dir[File.join(MYBOT_PATH, "recipes", "**", "*.rb")].flatten +
|
9
|
-
Dir[File.join(".mybot", "**", "*.rb")].flatten
|
10
|
-
Dir["Botfile"]
|
10
|
+
Dir[File.join(".mybot", "**", "*.rb")].flatten
|
11
11
|
).reject { |f| !File.exists?(f) }
|
12
12
|
end
|
13
13
|
|
data/lib/mybot/result.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mybot
|
2
|
+
class Result
|
3
|
+
attr_accessor :exit_status
|
4
|
+
attr_writer :stdout, :stderr
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@stdout = @stderr = ""
|
8
|
+
@exit_status = -1
|
9
|
+
end
|
10
|
+
|
11
|
+
def stdout
|
12
|
+
filter(@stdout)
|
13
|
+
end
|
14
|
+
|
15
|
+
def stderr
|
16
|
+
filter(@stderr)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def filter(data)
|
22
|
+
data.gsub(/\[sudo\]\ password\ for\ [a-zA-Z0-9_].+\:/, "")
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/mybot/utils.rb
ADDED
data/lib/mybot/version.rb
CHANGED
data/mybot.gemspec
CHANGED
data/vendor/lib/core/fs.rb
CHANGED
@@ -14,7 +14,7 @@ module Core
|
|
14
14
|
elsif options[:dir]
|
15
15
|
options[:cmd] = "test -e #{options[:dir]} && echo EXISTS"
|
16
16
|
end
|
17
|
-
@node.run(options).include?("EXISTS") ? true : false
|
17
|
+
@node.run(options).stdout.include?("EXISTS") ? true : false
|
18
18
|
end
|
19
19
|
|
20
20
|
def create(options = {})
|
@@ -23,13 +23,8 @@ module Core
|
|
23
23
|
end
|
24
24
|
|
25
25
|
if options[:file]
|
26
|
-
options[:
|
27
|
-
|
28
|
-
# do not use sudo when creating tmp file to be able to move file
|
29
|
-
sudo = options[:sudo]
|
30
|
-
options[:sudo] = false
|
31
|
-
tmp = @node.run(options)
|
32
|
-
options[:sudo] = sudo
|
26
|
+
options[:pattern] = "/tmp/mybot.XXXXX"
|
27
|
+
tmp = mktemp(options)
|
33
28
|
|
34
29
|
options[:content] ||= ""
|
35
30
|
@node.sftp.file.open(tmp, "w") { |f| f.write options[:content] }
|
@@ -41,6 +36,17 @@ module Core
|
|
41
36
|
end
|
42
37
|
end
|
43
38
|
|
39
|
+
def mktemp(options = {})
|
40
|
+
error "pattern required" unless options[:pattern]
|
41
|
+
|
42
|
+
options[:cmd] = "mktemp #{options[:pattern]}"
|
43
|
+
sudo = options[:sudo]
|
44
|
+
options[:sudo] = false
|
45
|
+
tmp = @node.run(options).stdout
|
46
|
+
options[:sudo] = sudo
|
47
|
+
tmp.strip
|
48
|
+
end
|
49
|
+
|
44
50
|
def remove(options = {})
|
45
51
|
unless options[:file] || options[:dir]
|
46
52
|
error "file or dir is required"
|
@@ -64,7 +70,7 @@ module Core
|
|
64
70
|
@node.fmt.error "read: file '#{options[:file]}' does not exists"
|
65
71
|
return ""
|
66
72
|
end
|
67
|
-
end
|
73
|
+
end.stdout
|
68
74
|
end
|
69
75
|
|
70
76
|
def upload(options = {})
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Core
|
2
|
+
module Osx
|
3
|
+
class Rails < Mybot::Lib
|
4
|
+
def initialize(node)
|
5
|
+
@node = node
|
6
|
+
@node.use [
|
7
|
+
"core/fs",
|
8
|
+
"core/osx/git"
|
9
|
+
]
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_release(options = {})
|
13
|
+
error "repo is required" unless options[:repo]
|
14
|
+
error "release is required" unless options[:release]
|
15
|
+
|
16
|
+
options[:dir] = "/tmp/#{options[:release]}"
|
17
|
+
@node.fs.remove(options)
|
18
|
+
|
19
|
+
options[:file] = "/tmp/#{options[:release]}.tar.gz"
|
20
|
+
@node.fs.remove(options)
|
21
|
+
|
22
|
+
options[:dest] = "/tmp/#{options[:release]}"
|
23
|
+
@node.git.clone(options)
|
24
|
+
|
25
|
+
options[:from] = "/tmp/#{options[:release]}"
|
26
|
+
options[:to] = "/tmp/#{options[:release]}.tar.gz"
|
27
|
+
@node.fs.compress(options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Core
|
2
|
+
module Osx
|
3
|
+
class Static < Mybot::Lib
|
4
|
+
def initialize(node)
|
5
|
+
@node = node
|
6
|
+
@node.use [
|
7
|
+
"core/fs",
|
8
|
+
"core/osx/git"
|
9
|
+
]
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_release(options = {})
|
13
|
+
error "repo is required" unless options[:repo]
|
14
|
+
error "release is required" unless options[:release]
|
15
|
+
|
16
|
+
options[:dir] = "/tmp/#{options[:release]}"
|
17
|
+
@node.fs.remove(options)
|
18
|
+
|
19
|
+
options[:file] = "/tmp/#{options[:release]}.tar.gz"
|
20
|
+
@node.fs.remove(options)
|
21
|
+
|
22
|
+
options[:dest] = "/tmp/#{options[:release]}"
|
23
|
+
@node.git.clone(options)
|
24
|
+
|
25
|
+
options[:from] = "/tmp/#{options[:release]}"
|
26
|
+
options[:to] = "/tmp/#{options[:release]}.tar.gz"
|
27
|
+
@node.fs.compress(options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -9,7 +9,15 @@ module Core
|
|
9
9
|
|
10
10
|
def update(options = {})
|
11
11
|
options[:cmd] = "#{DF} apt-get update"
|
12
|
-
@node.run(options)
|
12
|
+
@node.run(options) do |cmd|
|
13
|
+
cmd.on "dpkg was interrupted" do
|
14
|
+
dpkg_reconfigure(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
cmd.on "Could not get lock" do
|
18
|
+
error "Cannot update"
|
19
|
+
end
|
20
|
+
end
|
13
21
|
end
|
14
22
|
|
15
23
|
def upgrade(options = {})
|
@@ -26,7 +34,11 @@ module Core
|
|
26
34
|
error "pkg not specified" unless options[:pkg]
|
27
35
|
|
28
36
|
options[:cmd] = "#{DF} apt-get install -y #{options[:pkg]}"
|
29
|
-
@node.run(options)
|
37
|
+
@node.run(options) do |cmd|
|
38
|
+
cmd.on "dpkg was interrupted" do
|
39
|
+
dpkg_reconfigure(options)
|
40
|
+
end
|
41
|
+
end
|
30
42
|
end
|
31
43
|
|
32
44
|
def remove(options = {})
|
@@ -35,6 +47,11 @@ module Core
|
|
35
47
|
options[:cmd] = "#{DF} apt-get --purge autoremove -y #{options[:pkg]}"
|
36
48
|
@node.run(options)
|
37
49
|
end
|
50
|
+
|
51
|
+
def dpkg_reconfigure(options = {})
|
52
|
+
options[:cmd] = "#{DF} dpkg --configure -a"
|
53
|
+
@node.run(options)
|
54
|
+
end
|
38
55
|
end
|
39
56
|
end
|
40
57
|
end
|
@@ -31,6 +31,18 @@ module Core
|
|
31
31
|
options[:cmd] = "git clone #{options[:repo]} #{options[:dest]}"
|
32
32
|
@node.run(options)
|
33
33
|
end
|
34
|
+
|
35
|
+
def init(options = {})
|
36
|
+
error "repo not specified" unless options[:repo]
|
37
|
+
|
38
|
+
options[:cmd] = "git init #{options[:repo]}"
|
39
|
+
|
40
|
+
if options[:bare]
|
41
|
+
options[:cmd] += " --bare"
|
42
|
+
end
|
43
|
+
|
44
|
+
@node.run(options)
|
45
|
+
end
|
34
46
|
end
|
35
47
|
end
|
36
48
|
end
|