mybot 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,6 +1,7 @@
|
|
1
1
|
module Core
|
2
2
|
module Ubuntu
|
3
3
|
class Mysql < Mybot::Lib
|
4
|
+
PROMPT = "mysql -u %s --password=%s -e \"%s\""
|
4
5
|
|
5
6
|
def initialize(node)
|
6
7
|
@node = node
|
@@ -78,6 +79,136 @@ module Core
|
|
78
79
|
options[:dir] = "/var/lib/mysql"
|
79
80
|
@node.fs.remove(options)
|
80
81
|
end
|
82
|
+
|
83
|
+
def database_list(options = {})
|
84
|
+
error "root_password is required" unless options[:root_password]
|
85
|
+
|
86
|
+
query = "SHOW DATABASES;"
|
87
|
+
options[:cmd] = sprintf(PROMPT, "root", options[:root_password], query)
|
88
|
+
|
89
|
+
databases = @node.run(options).stdout.split("\r\n")
|
90
|
+
databases[3..-2].map do |db|
|
91
|
+
db.gsub("|", "").strip
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def database_exists?(options = {})
|
96
|
+
error "database is required" unless options[:database]
|
97
|
+
|
98
|
+
database_list(options).include?(options[:database])
|
99
|
+
end
|
100
|
+
|
101
|
+
def database_create(options = {})
|
102
|
+
error "root_password is required" unless options[:root_password]
|
103
|
+
error "database is required" unless options[:database]
|
104
|
+
|
105
|
+
options[:character_set] ||= "utf8"
|
106
|
+
options[:collate] ||= "utf8_general_ci"
|
107
|
+
|
108
|
+
query = sprintf("CREATE DATABASE %s CHARACTER SET %s COLLATE %s;",
|
109
|
+
options[:database], options[:character_set], options[:collate])
|
110
|
+
|
111
|
+
options[:cmd] = sprintf(PROMPT, "root", options[:root_password], query)
|
112
|
+
@node.run(options)
|
113
|
+
end
|
114
|
+
|
115
|
+
def database_remove(options = {})
|
116
|
+
error "root_password is required" unless options[:root_password]
|
117
|
+
error "database is required" unless options[:database]
|
118
|
+
|
119
|
+
query = sprintf("DROP DATABASE %s;", options[:database])
|
120
|
+
|
121
|
+
options[:cmd] = sprintf(PROMPT, "root", options[:root_password], query)
|
122
|
+
@node.run(options)
|
123
|
+
end
|
124
|
+
|
125
|
+
def user_list(options = {})
|
126
|
+
error "root_password is required" unless options[:root_password]
|
127
|
+
|
128
|
+
query = "USE mysql; SELECT User from user;"
|
129
|
+
options[:cmd] = sprintf(PROMPT, "root", options[:root_password], query)
|
130
|
+
users = @node.run(options).stdout.split("\r\n")
|
131
|
+
users[3..-2].map do |u|
|
132
|
+
u.gsub("|", "").strip
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def user_exists?(options = {})
|
137
|
+
user_list(options).include?(options[:username])
|
138
|
+
end
|
139
|
+
|
140
|
+
def user_create(options = {})
|
141
|
+
error "root_password is required" unless options[:root_password]
|
142
|
+
error "username is required" unless options[:username]
|
143
|
+
error "password is required" unless options[:password]
|
144
|
+
|
145
|
+
options[:host] ||= "localhost"
|
146
|
+
|
147
|
+
query = "CREATE USER '#{options[:username]}'@"
|
148
|
+
query += "'#{options[:host]}' IDENTIFIED BY '#{options[:password]}';"
|
149
|
+
|
150
|
+
options[:cmd] = sprintf(PROMPT, "root", options[:root_password], query)
|
151
|
+
@node.run(options)
|
152
|
+
end
|
153
|
+
|
154
|
+
def user_remove(options = {})
|
155
|
+
error "root_password is required" unless options[:root_password]
|
156
|
+
error "username is required" unless options[:username]
|
157
|
+
|
158
|
+
options[:host] ||= "localhost"
|
159
|
+
|
160
|
+
query = "DROP USER '#{options[:username]}'@'#{options[:host]}';"
|
161
|
+
|
162
|
+
options[:cmd] = sprintf(PROMPT, "root", options[:root_password], query)
|
163
|
+
@node.run(options)
|
164
|
+
end
|
165
|
+
|
166
|
+
def grant_privileges(options = {})
|
167
|
+
error "root_password is required" unless options[:root_password]
|
168
|
+
error "username is required" unless options[:username]
|
169
|
+
|
170
|
+
options[:host] ||= "localhost"
|
171
|
+
options[:database] ||= "*"
|
172
|
+
options[:table] ||= "*"
|
173
|
+
|
174
|
+
query = sprintf("GRANT ALL PRIVILEGES ON %s.%s TO '%s'@'%s';",
|
175
|
+
options[:database], options[:table], options[:username],
|
176
|
+
options[:host])
|
177
|
+
|
178
|
+
options[:cmd] = sprintf(PROMPT, "root", options[:root_password], query)
|
179
|
+
@node.run(options)
|
180
|
+
end
|
181
|
+
|
182
|
+
def flush_privileges(options = {})
|
183
|
+
error "root_password is required" unless options[:root_password]
|
184
|
+
|
185
|
+
query = "FLUSH PRIVILEGES;"
|
186
|
+
|
187
|
+
options[:cmd] = sprintf(PROMPT, "root", options[:root_password], query)
|
188
|
+
@node.run(options)
|
189
|
+
end
|
190
|
+
|
191
|
+
def dump(options = {})
|
192
|
+
error "root_password is required" unless options[:root_password]
|
193
|
+
error "database is required" unless options[:database]
|
194
|
+
|
195
|
+
tmp = @node.fs.mktemp({ :pattern => "/tmp/dump.XXXX" })
|
196
|
+
|
197
|
+
options[:cmd] = sprintf("mysqldump -u %s --password=%s %s > %s",
|
198
|
+
"root", options[:root_password], options[:database], tmp)
|
199
|
+
@node.run(options)
|
200
|
+
tmp
|
201
|
+
end
|
202
|
+
|
203
|
+
def load(options = {})
|
204
|
+
error "root_password is required" unless options[:root_password]
|
205
|
+
error "database is required" unless options[:database]
|
206
|
+
error "file is required" unless options[:file]
|
207
|
+
|
208
|
+
options[:cmd] = sprintf("mysql -u %s --password=%s %s < %s",
|
209
|
+
"root", options[:root_password], options[:database], options[:file])
|
210
|
+
@node.run(options)
|
211
|
+
end
|
81
212
|
end
|
82
213
|
end
|
83
214
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Core
|
2
|
+
module Ubuntu
|
3
|
+
class Nginx < Mybot::Lib
|
4
|
+
def initialize(node)
|
5
|
+
@node = node
|
6
|
+
@node.use [
|
7
|
+
"core/fs",
|
8
|
+
"core/ubuntu/apt",
|
9
|
+
"core/ubuntu/service"
|
10
|
+
]
|
11
|
+
|
12
|
+
@nginxconf_tpl = tpl_file "core/ubuntu/nginx/nginx.conf.erb"
|
13
|
+
end
|
14
|
+
|
15
|
+
def installed?(options = {})
|
16
|
+
@node.fs.exists?({ :file => "/usr/sbin/nginx"} )
|
17
|
+
end
|
18
|
+
|
19
|
+
def install(options = {})
|
20
|
+
options[:pkg] = "nginx"
|
21
|
+
@node.apt.install(options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove(options = {})
|
25
|
+
options[:pkg] = "nginx"
|
26
|
+
@node.apt.remove(options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def reconfigure(options = {})
|
30
|
+
error "config is required" unless options[:config]
|
31
|
+
|
32
|
+
options[:file] = "/etc/nginx/nginx.conf"
|
33
|
+
@node.fs.remove(options)
|
34
|
+
|
35
|
+
options[:content] = @nginxconf_tpl.render(options[:config])
|
36
|
+
@node.fs.create(options)
|
37
|
+
|
38
|
+
options[:service] = "nginx"
|
39
|
+
@node.service.restart(options)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Core
|
2
|
+
module Ubuntu
|
3
|
+
class Php < Mybot::Lib
|
4
|
+
def initialize(node)
|
5
|
+
@node = node
|
6
|
+
@node.use [
|
7
|
+
"core/fs",
|
8
|
+
"core/ubuntu/apt",
|
9
|
+
"core/ubuntu/service"
|
10
|
+
]
|
11
|
+
@phpini_tpl = tpl_file "core/ubuntu/php/php.ini.erb"
|
12
|
+
end
|
13
|
+
|
14
|
+
def installed?(options = {})
|
15
|
+
options[:file] = "/usr/bin/php"
|
16
|
+
@node.fs.exists?(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def install(options = {})
|
20
|
+
options[:pkg] = "php5-common php5-cli php5-fpm"
|
21
|
+
@node.apt.install(options)
|
22
|
+
|
23
|
+
options[:service] = "php5-fpm"
|
24
|
+
@node.service.restart(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove(options = {})
|
28
|
+
options[:service] = "php5-fpm"
|
29
|
+
@node.service.stop(options)
|
30
|
+
|
31
|
+
options[:pkg] = "php5-common php5-cli php5-fpm"
|
32
|
+
@node.apt.remove(options)
|
33
|
+
end
|
34
|
+
|
35
|
+
def ext_installed?(options = {})
|
36
|
+
error "ext is required" unless options[:ext]
|
37
|
+
|
38
|
+
options[:file] = "/usr/lib/php5/20100525/#{options[:ext]}.so"
|
39
|
+
@node.fs.exists?(options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def ext_install(options = {})
|
43
|
+
error "ext is required" unless options[:ext]
|
44
|
+
|
45
|
+
options[:pkg] = "php5-#{options[:ext]}"
|
46
|
+
@node.apt.install(options)
|
47
|
+
|
48
|
+
options[:service] = "php5-fpm"
|
49
|
+
@node.service.restart(options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def ext_remove(options = {})
|
53
|
+
error "ext is required" unless options[:ext]
|
54
|
+
|
55
|
+
options[:pkg] = "php5-#{options[:ext]}"
|
56
|
+
@node.apt.remove(options)
|
57
|
+
|
58
|
+
options[:service] = "php5-fpm"
|
59
|
+
@node.service.restart(options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def reconfigure(options = {})
|
63
|
+
error "config is required" unless options[:config]
|
64
|
+
|
65
|
+
options[:file] = "/etc/php5/fpm/php.ini"
|
66
|
+
@node.fs.remove(options)
|
67
|
+
|
68
|
+
options[:content] = @phpini_tpl.render(options[:config])
|
69
|
+
@node.fs.create(options)
|
70
|
+
|
71
|
+
options[:service] = "php5-fpm"
|
72
|
+
@node.service.restart(options)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Core
|
2
|
+
module Ubuntu
|
3
|
+
class Rails < Mybot::Lib
|
4
|
+
def initialize(node)
|
5
|
+
@node = node
|
6
|
+
@node.use [
|
7
|
+
"core/fs",
|
8
|
+
"core/ubuntu/ruby"
|
9
|
+
]
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup_deployment(options = {})
|
13
|
+
error "app_name is required" unless options[:app_name]
|
14
|
+
|
15
|
+
dirs = [
|
16
|
+
"/home/#{options[:app_name]}/releases",
|
17
|
+
"/home/#{options[:app_name]}/shared",
|
18
|
+
"/home/#{options[:app_name]}/shared/bundle",
|
19
|
+
"/home/#{options[:app_name]}/shared/log",
|
20
|
+
"/home/#{options[:app_name]}/shared/pids",
|
21
|
+
"/home/#{options[:app_name]}/shared/system",
|
22
|
+
]
|
23
|
+
|
24
|
+
dirs.each do |d|
|
25
|
+
options[:dir] = d
|
26
|
+
@node.fs.require_created(options)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def deploy(options = {})
|
31
|
+
error "app_name is required" unless options[:app_name]
|
32
|
+
error "release is required" unless options[:release]
|
33
|
+
|
34
|
+
releases_path = "/home/#{options[:app_name]}/releases"
|
35
|
+
release_path = "#{releases_path}/#{options[:release]}"
|
36
|
+
shared_path = "/home/#{options[:app_name]}/shared"
|
37
|
+
current_path = "/home/#{options[:app_name]}/current"
|
38
|
+
|
39
|
+
# upload release archive
|
40
|
+
options[:from] = options[:to] = "/tmp/#{options[:release]}.tar.gz"
|
41
|
+
@node.fs.upload(options)
|
42
|
+
|
43
|
+
# extract archive
|
44
|
+
options[:to] = releases_path
|
45
|
+
@node.fs.extract(options)
|
46
|
+
|
47
|
+
# install bundle
|
48
|
+
options[:ruby_version] = "1.9.3-p194"
|
49
|
+
options[:cmd] = "bundle install " +
|
50
|
+
"--gemfile #{release_path}/Gemfile " +
|
51
|
+
"--path /home/#{options[:app_name]}/shared/bundle " +
|
52
|
+
"--deployment --without development test"
|
53
|
+
options[:cwd] = release_path
|
54
|
+
@node.ruby.rbenv_exec(options)
|
55
|
+
|
56
|
+
# link public/system
|
57
|
+
options[:dir] = "#{release_path}/public/system"
|
58
|
+
@node.fs.remove(options)
|
59
|
+
|
60
|
+
options[:dir] = "#{release_path}/public"
|
61
|
+
@node.fs.require_created(options)
|
62
|
+
|
63
|
+
options[:from] = "#{shared_path}/public/system"
|
64
|
+
options[:to] = "#{release_path}/public/system"
|
65
|
+
@node.fs.link(options)
|
66
|
+
|
67
|
+
# link log
|
68
|
+
options[:dir] = "#{release_path}/log"
|
69
|
+
@node.fs.remove(options)
|
70
|
+
|
71
|
+
options[:from] = "#{shared_path}/log"
|
72
|
+
options[:to] = "#{release_path}/log"
|
73
|
+
@node.fs.link(options)
|
74
|
+
|
75
|
+
# link tmp/pids
|
76
|
+
options[:dir] = "#{release_path}/tmp/pids"
|
77
|
+
@node.fs.remove(options)
|
78
|
+
|
79
|
+
options[:dir] = "#{release_path}/tmp"
|
80
|
+
@node.fs.require_created(options)
|
81
|
+
|
82
|
+
options[:from] = "#{shared_path}/pids"
|
83
|
+
options[:to] = "#{release_path}/tmp/pids"
|
84
|
+
@node.fs.link(options)
|
85
|
+
|
86
|
+
# link current
|
87
|
+
options[:dir] = current_path
|
88
|
+
@node.fs.remove(options)
|
89
|
+
|
90
|
+
options[:from] = release_path
|
91
|
+
options[:to] = current_path
|
92
|
+
@node.fs.link(options)
|
93
|
+
|
94
|
+
# restart passenger
|
95
|
+
options[:file] = "#{release_path}/tmp/restart.txt"
|
96
|
+
|
97
|
+
# repair permissions
|
98
|
+
options[:dir] = "/home/#{options[:app_name]}"
|
99
|
+
options[:user] = options[:app_name]
|
100
|
+
options[:group] = options[:app_name]
|
101
|
+
@node.fs.chown(options)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -38,6 +38,7 @@ module Core
|
|
38
38
|
options[:pkg] = "ruby-build"
|
39
39
|
@node.apt.install(options)
|
40
40
|
|
41
|
+
options.delete(:file)
|
41
42
|
options[:dir] = RBENV_ROOT
|
42
43
|
@node.fs.create(options)
|
43
44
|
end
|
@@ -58,7 +59,7 @@ module Core
|
|
58
59
|
"RBENV_ROOT" => RBENV_ROOT
|
59
60
|
}
|
60
61
|
options[:cmd] = "rbenv versions"
|
61
|
-
versions = @node.run(options)
|
62
|
+
versions = @node.run(options).stdout
|
62
63
|
versions.split("\r\n").map { |v| v.strip }
|
63
64
|
end
|
64
65
|
|
@@ -102,14 +103,14 @@ module Core
|
|
102
103
|
}
|
103
104
|
|
104
105
|
options[:cmd] = "rbenv exec #{options[:cmd]}"
|
105
|
-
@node.run(options)
|
106
|
+
@node.run(options).stdout
|
106
107
|
end
|
107
108
|
|
108
109
|
def rbenv_gem_list(options = {})
|
109
110
|
options[:cmd] = "gem list"
|
110
111
|
gems = rbenv_exec(options)
|
111
112
|
gems = gems.split("\r\n").reject do |g|
|
112
|
-
g == "" || g == "*** LOCAL GEMS ***"
|
113
|
+
g.strip == "" || g == "*** LOCAL GEMS ***"
|
113
114
|
end.map do |g|
|
114
115
|
parts = g.split("(")
|
115
116
|
{
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Core
|
2
|
+
module Ubuntu
|
3
|
+
class Static < Mybot::Lib
|
4
|
+
def initialize(node)
|
5
|
+
@node = node
|
6
|
+
@node.use [
|
7
|
+
"core/fs"
|
8
|
+
]
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup_deployment(options = {})
|
12
|
+
error "app_name is required" unless options[:app_name]
|
13
|
+
|
14
|
+
options[:dir] = "/home/#{options[:app_name]}/releases"
|
15
|
+
@node.fs.require_created(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def deploy(options = {})
|
19
|
+
error "app_name is required" unless options[:app_name]
|
20
|
+
error "release is required" unless options[:release]
|
21
|
+
|
22
|
+
releases_path = "/home/#{options[:app_name]}/releases"
|
23
|
+
release_path = "#{releases_path}/#{options[:release]}"
|
24
|
+
current_path = "/home/#{options[:app_name]}/current"
|
25
|
+
|
26
|
+
# upload release archive
|
27
|
+
options[:from] = options[:to] = "/tmp/#{options[:release]}.tar.gz"
|
28
|
+
@node.fs.upload(options)
|
29
|
+
|
30
|
+
# extract archive
|
31
|
+
options[:to] = releases_path
|
32
|
+
@node.fs.extract(options)
|
33
|
+
|
34
|
+
# link current
|
35
|
+
options[:dir] = current_path
|
36
|
+
@node.fs.remove(options)
|
37
|
+
|
38
|
+
options[:from] = release_path
|
39
|
+
options[:to] = current_path
|
40
|
+
@node.fs.link(options)
|
41
|
+
|
42
|
+
# repair permissions
|
43
|
+
options[:dir] = "/home/#{options[:app_name]}"
|
44
|
+
options[:user] = options[:app_name]
|
45
|
+
options[:group] = options[:app_name]
|
46
|
+
@node.fs.chown(options)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|