capricorn 2.0.6 → 2.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/capricornctl +1 -1
- data/lib/capricorn-client.rb +33 -62
- data/lib/capricorn-client/cli/applications.rb +124 -197
- data/lib/capricorn-client/cli/applications/domains.rb +61 -0
- data/lib/capricorn-client/cli/applications/gems.rb +61 -0
- data/lib/capricorn-client/cli/gems.rb +38 -16
- data/lib/capricorn-client/cli/machines.rb +17 -8
- data/lib/capricorn-client/helpers.rb +194 -48
- data/lib/capricorn/version.rb +1 -1
- metadata +30 -28
data/bin/capricornctl
CHANGED
data/lib/capricorn-client.rb
CHANGED
@@ -2,85 +2,56 @@ module Capricorn
|
|
2
2
|
require 'thor'
|
3
3
|
require 'yaml'
|
4
4
|
require 'bertrpc'
|
5
|
-
require 'highline'
|
6
5
|
require 'fileutils'
|
7
6
|
|
8
7
|
require 'capricorn-client/helpers'
|
9
8
|
|
10
|
-
|
9
|
+
class CLI < Thor
|
10
|
+
namespace "default"
|
11
|
+
|
11
12
|
require 'capricorn-client/cli/applications'
|
13
|
+
require 'capricorn-client/cli/applications/domains'
|
14
|
+
require 'capricorn-client/cli/applications/gems'
|
12
15
|
require 'capricorn-client/cli/gems'
|
13
16
|
require 'capricorn-client/cli/machines'
|
14
|
-
end
|
15
|
-
|
16
|
-
module Runner
|
17
|
-
|
18
|
-
HELP = <<-EOH
|
19
|
-
Topics:
|
20
|
-
CLUSTER applications
|
21
|
-
# manage applications
|
22
|
-
|
23
|
-
CLUSTER gems
|
24
|
-
# manage gems
|
25
|
-
|
26
|
-
CLUSTER machines
|
27
|
-
# manage machines
|
28
|
-
EOH
|
29
|
-
|
30
|
-
DEFAULT_CONFIG = <<-EOH
|
31
|
-
cluster_name:
|
32
|
-
host: localhost
|
33
|
-
port: 3457
|
34
|
-
username: dummy
|
35
|
-
password: dummy
|
36
|
-
EOH
|
37
|
-
|
38
|
-
def start
|
39
|
-
cluster_name = ARGV.shift
|
40
|
-
unless cluster_name
|
41
|
-
help
|
42
|
-
exit 1
|
43
|
-
end
|
44
17
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
exit 1
|
49
|
-
end
|
18
|
+
def self.banner(task)
|
19
|
+
"#{banner_base} #{task.formatted_usage(self, true)}"
|
20
|
+
end
|
50
21
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
Capricorn::CLI::Gems.start
|
56
|
-
when 'machines'
|
57
|
-
Capricorn::CLI::Machines.start
|
22
|
+
def help(meth=nil)
|
23
|
+
if meth && !self.respond_to?(meth)
|
24
|
+
klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
|
25
|
+
klass.start(["-h", task].compact, :shell => self.shell)
|
58
26
|
else
|
59
|
-
|
27
|
+
super
|
60
28
|
end
|
61
29
|
end
|
62
30
|
|
63
|
-
def
|
64
|
-
|
31
|
+
def method_missing(meth, *args)
|
32
|
+
meth = meth.to_s
|
33
|
+
klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
|
34
|
+
args.unshift(task) if task
|
35
|
+
klass.start(args, :shell => self.shell)
|
65
36
|
end
|
66
37
|
|
67
|
-
|
68
|
-
|
69
|
-
|
38
|
+
class_option :cluster, :type => :string, :aliases => ['-c']
|
39
|
+
class_option :machine, :type => :string, :aliases => ['-m', '-n', '--node']
|
40
|
+
class_option :application, :type => :string, :aliases => ['-a', '--app']
|
41
|
+
class_option :environment, :type => :string, :aliases => ['-e', '--env']
|
70
42
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
43
|
+
desc "deploy", "deploy an new gem"
|
44
|
+
def deploy
|
45
|
+
last = Dir.glob("pkg/*.gem").sort do |a, b|
|
46
|
+
File.stat(a).mtime <=> File.stat(b).mtime
|
47
|
+
end.last
|
48
|
+
|
49
|
+
$capr_gems_weak_push = true
|
50
|
+
|
51
|
+
invoke "gems:push", [last]
|
52
|
+
invoke "apps:fupdate"
|
82
53
|
end
|
83
54
|
|
84
|
-
extend self
|
85
55
|
end
|
56
|
+
|
86
57
|
end
|
@@ -1,256 +1,183 @@
|
|
1
|
-
class Capricorn::CLI::Applications <
|
1
|
+
class Capricorn::CLI::Applications < Capricorn::CLI
|
2
|
+
|
3
|
+
require 'public_suffix_service'
|
4
|
+
|
2
5
|
include Capricorn::Helpers
|
3
|
-
|
6
|
+
|
7
|
+
namespace :apps
|
8
|
+
|
9
|
+
desc "init", "initialize the .capricorn.yml file"
|
10
|
+
def init
|
11
|
+
if File.file?('.capricorn.yml')
|
12
|
+
halt ".capricorn.yml already exists"
|
13
|
+
end
|
14
|
+
|
15
|
+
File.open(".capricorn.yml", 'w+') do |file|
|
16
|
+
file.write <<-EOS
|
17
|
+
staging:
|
18
|
+
cluster: CLUSTER_NAME
|
19
|
+
machine: MACHINE_ID
|
20
|
+
application: APPLICATION_ID
|
21
|
+
EOS
|
22
|
+
end
|
23
|
+
info "initialized .capricorn.yml"
|
24
|
+
end
|
25
|
+
|
4
26
|
desc "list", "list all applications on MACHINE"
|
5
27
|
def list
|
6
|
-
machine = select_machine
|
7
|
-
|
8
28
|
apps = client.call.applications.all(machine.to_sym).last || []
|
9
29
|
apps.collect! do |app|
|
10
|
-
[app[
|
30
|
+
[app[3], app[1]]
|
11
31
|
end
|
12
|
-
apps.
|
13
|
-
|
14
|
-
ui.table %w( Id Name ), apps, :columns_across, 2
|
15
|
-
end
|
16
|
-
|
17
|
-
desc "info", "get info of an application on MACHINE"
|
18
|
-
def info
|
19
|
-
machine, id = *select_application
|
20
|
-
app = find_app(machine, id)
|
21
|
-
show_app(app)
|
22
|
-
end
|
23
|
-
|
24
|
-
desc "create", "create an application on MACHINE"
|
25
|
-
def create
|
26
|
-
machine = select_machine
|
27
|
-
name = ui.ask("name: ") do |q|
|
28
|
-
q.validate = /^.+$/
|
32
|
+
apps.sort! do |a,b|
|
33
|
+
a[0] <=> b[0]
|
29
34
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
width = apps.inject(0) { |m, (n, _)| (m > n.size ? m : n.size) }
|
36
|
+
|
37
|
+
apps.each do |(name, id)|
|
38
|
+
padding = ' ' * (width - name.size)
|
39
|
+
puts "#{name}#{padding} : #{id}"
|
34
40
|
end
|
35
|
-
|
36
|
-
|
37
|
-
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "show", "get info of an application on MACHINE"
|
44
|
+
def show
|
45
|
+
puts " Id: #{application_info[1]}"
|
46
|
+
puts " Machine: #{application_info[2]}"
|
47
|
+
puts " Name: #{application_info[3]}"
|
48
|
+
puts " Environment: #{application_info[5]}"
|
49
|
+
puts " User: #{application_info[6]}"
|
50
|
+
puts " Group: #{application_info[7]}"
|
51
|
+
puts " Root: #{application_info[8]}"
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "create NAME ENVIRONMENT DOMAINS...", "create an application on MACHINE"
|
55
|
+
def create(name, environment, *domains)
|
56
|
+
name = name.to_s.strip
|
57
|
+
if name.empty?
|
58
|
+
halt "Please choose a name!"
|
59
|
+
end
|
60
|
+
|
61
|
+
environment = environment.to_s.strip
|
62
|
+
unless %w( production development staging testing ).include?(environment)
|
63
|
+
halt "Please select a valid environment!"
|
38
64
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
65
|
+
environment = environment.to_sym
|
66
|
+
|
67
|
+
domains = domains.flatten do |domain|
|
68
|
+
if domain
|
69
|
+
domain = domain.to_s.downcase.strip.sub(/^www\./, '')
|
70
|
+
begin
|
71
|
+
PublicSuffixService.parse(domain).to_s
|
72
|
+
rescue Exception
|
73
|
+
halt "invalid domain: #{domain}"
|
74
|
+
end
|
42
75
|
end
|
43
|
-
|
44
|
-
|
76
|
+
end.compact.uniq
|
77
|
+
domains.delete('')
|
78
|
+
if domains.empty?
|
79
|
+
halt "Please add at least one domain!"
|
45
80
|
end
|
46
|
-
|
47
|
-
domains = domains.flatten.compact
|
48
|
-
domains = domains.collect { |d| d.downcase.sub(/^www\./, '') }
|
49
|
-
domains = domains.uniq
|
50
|
-
|
51
|
-
environment = environment.to_sym
|
52
|
-
|
81
|
+
|
53
82
|
p client.call.applications.create(machine.to_sym, name, domains, environment)
|
54
83
|
end
|
55
|
-
|
56
|
-
desc "import", "import an application on MACHINE (only use this from an application dir)"
|
57
|
-
def import
|
84
|
+
|
85
|
+
desc "import NAME ENVIRONMENT DOMAINS...", "import an application on MACHINE (only use this from an application dir)"
|
86
|
+
def import(name, environment, *domains)
|
58
87
|
root = File.expand_path(Dir.pwd)
|
59
|
-
|
88
|
+
|
60
89
|
unless File.file?(File.join(root, "host/config/milkshake.yml"))
|
61
|
-
|
62
|
-
|
63
|
-
exit 1
|
90
|
+
info 'no milkshake config was found'
|
91
|
+
halt 'This doesn\'t appear to be a milkshake app!'
|
64
92
|
end
|
65
|
-
|
93
|
+
|
66
94
|
unless File.directory?(File.join(root, "shared"))
|
67
|
-
|
68
|
-
|
69
|
-
exit 1
|
95
|
+
info 'no shared dir was found'
|
96
|
+
halt 'This doesn\'t appear to be a milkshake app!'
|
70
97
|
end
|
71
|
-
|
98
|
+
|
72
99
|
gems = YAML.load_file(File.join(root, "host/config/milkshake.yml"))
|
73
100
|
gems = (gems['gems'].keys rescue [])
|
74
101
|
if gems.empty?
|
75
|
-
|
76
|
-
|
77
|
-
exit 1
|
102
|
+
info 'no gems were found'
|
103
|
+
halt 'This doesn\'t appear to be a milkshake app!'
|
78
104
|
end
|
79
|
-
|
105
|
+
|
80
106
|
stats = (File.stat(File.join(root, "host/config/environment.rb")) rescue nil)
|
81
107
|
unless stats
|
82
|
-
|
83
|
-
|
84
|
-
exit 1
|
108
|
+
info 'no environment.rb was found'
|
109
|
+
halt 'This doesn\'t appear to be a milkshake app!'
|
85
110
|
end
|
86
|
-
|
111
|
+
|
87
112
|
uid = (Etc.getpwuid(stats.uid).name rescue nil)
|
88
113
|
unless uid
|
89
|
-
|
90
|
-
|
91
|
-
exit 1
|
114
|
+
info 'no uid was found'
|
115
|
+
halt 'This doesn\'t appear to be a milkshake app!'
|
92
116
|
end
|
93
|
-
|
117
|
+
|
94
118
|
gid = (Etc.getgrgid(stats.gid).name rescue nil)
|
95
119
|
unless gid
|
96
|
-
|
97
|
-
|
98
|
-
exit 1
|
99
|
-
end
|
100
|
-
|
101
|
-
machine = select_machine
|
102
|
-
name = ui.ask("name: ") do |q|
|
103
|
-
q.validate = /^.+$/
|
104
|
-
end
|
105
|
-
environment = ui.choose do |q|
|
106
|
-
q.choices(*%w( production development staging testing ))
|
107
|
-
q.prompt = "environment: "
|
108
|
-
q.default = 'production'
|
120
|
+
info 'no gid was found'
|
121
|
+
halt 'This doesn\'t appear to be a milkshake app!'
|
109
122
|
end
|
110
|
-
|
111
|
-
|
112
|
-
|
123
|
+
|
124
|
+
name = name.to_s.strip
|
125
|
+
if name.empty?
|
126
|
+
halt "Please choose a name!"
|
113
127
|
end
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
break if domain.strip.empty?
|
119
|
-
domains << domain
|
128
|
+
|
129
|
+
environment = environment.to_s.strip
|
130
|
+
unless %w( production development staging testing ).include?(environment)
|
131
|
+
halt "Please select a valid environment!"
|
120
132
|
end
|
121
|
-
|
122
|
-
domains = domains.flatten.compact
|
123
|
-
domains = domains.collect { |d| d.downcase.sub(/^www\./, '') }
|
124
|
-
domains = domains.uniq
|
125
|
-
|
126
133
|
environment = environment.to_sym
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
app[4] ||= []
|
137
|
-
app[9] ||= []
|
138
|
-
app[10] ||= []
|
139
|
-
|
140
|
-
loop do
|
141
|
-
print "\e[H\e[2J" ; $stdout.flush
|
142
|
-
|
143
|
-
show_app(app)
|
144
|
-
|
145
|
-
puts
|
146
|
-
|
147
|
-
ui.choose do |q|
|
148
|
-
q.header = "Actions"
|
149
|
-
q.prompt = 'What do you wan to do? '
|
150
|
-
|
151
|
-
q.choice('gem-add') do
|
152
|
-
name = ui.ask("enter a gem name: ") do |q|
|
153
|
-
q.validate = /^([a-zA-Z0-9_-]+)?$/
|
154
|
-
end
|
155
|
-
app[10] << name unless name.strip.empty?
|
134
|
+
|
135
|
+
domains = domains.flatten do |domain|
|
136
|
+
if domain
|
137
|
+
domain = domain.to_s.downcase.strip.sub(/^www\./, '')
|
138
|
+
begin
|
139
|
+
PublicSuffixService.parse(domain).to_s
|
140
|
+
rescue Exception
|
141
|
+
halt "invalid domain: #{domain}"
|
156
142
|
end
|
157
|
-
|
158
|
-
q.choice('gem-remove') do
|
159
|
-
g = ui.choose do |q|
|
160
|
-
q.header = "Gems"
|
161
|
-
q.prompt = 'choose a gem to remove: '
|
162
|
-
q.choices(*app[10])
|
163
|
-
end
|
164
|
-
app[10].delete(g)
|
165
|
-
end
|
166
|
-
|
167
|
-
q.choice('domain-add') do
|
168
|
-
domain = ui.ask("enter a domain: ") do |q|
|
169
|
-
q.validate = /^([\w\d]+(\.[\w\d]+)*)?$/
|
170
|
-
end
|
171
|
-
app[4] << domain unless domain.strip.empty?
|
172
|
-
end
|
173
|
-
|
174
|
-
q.choice('domain-remove') do
|
175
|
-
domain = ui.choose do |q|
|
176
|
-
q.header = "Domains"
|
177
|
-
q.prompt = 'choose a domain to remove: '
|
178
|
-
q.choices(*app[4])
|
179
|
-
end
|
180
|
-
app[4].delete(domain)
|
181
|
-
end
|
182
|
-
|
183
|
-
q.choice('abort') do
|
184
|
-
exit(0)
|
185
|
-
end
|
186
|
-
|
187
|
-
q.choice('commit') do
|
188
|
-
p client.call.applications.update(machine.to_sym, id, app[4], app[10])
|
189
|
-
exit(0)
|
190
|
-
end
|
191
|
-
|
192
143
|
end
|
144
|
+
end.compact.uniq
|
145
|
+
domains.delete('')
|
146
|
+
if domains.empty?
|
147
|
+
halt "Please add at least one domain!"
|
193
148
|
end
|
149
|
+
|
150
|
+
p client.call.applications.import(machine.to_sym, name, domains, environment, root, gems, uid, gid)
|
194
151
|
end
|
195
|
-
|
152
|
+
|
196
153
|
desc "fupdate", "force update an application on MACHINE"
|
197
154
|
def fupdate
|
198
|
-
machine, id = *
|
155
|
+
machine, id = *application
|
199
156
|
p client.call.applications.fupdate(machine.to_sym, id)
|
200
157
|
end
|
201
|
-
|
158
|
+
|
202
159
|
desc "relink", "relink an application on MACHINE"
|
203
160
|
def relink
|
204
|
-
machine, id = *
|
161
|
+
machine, id = *application
|
205
162
|
p client.call.applications.relink(machine.to_sym, id)
|
206
163
|
end
|
207
|
-
|
164
|
+
|
208
165
|
desc "restart", "restart an application on MACHINE"
|
209
166
|
def restart
|
210
|
-
machine, id = *
|
167
|
+
machine, id = *application
|
211
168
|
p client.call.applications.restart(machine.to_sym, id)
|
212
169
|
end
|
213
|
-
|
170
|
+
|
214
171
|
desc "start", "start an application on MACHINE"
|
215
172
|
def start
|
216
|
-
machine, id = *
|
173
|
+
machine, id = *application
|
217
174
|
p client.call.applications.start(machine.to_sym, id)
|
218
175
|
end
|
219
|
-
|
176
|
+
|
220
177
|
desc "stop", "stop an application on MACHINE"
|
221
178
|
def stop
|
222
|
-
machine, id = *
|
179
|
+
machine, id = *application
|
223
180
|
p client.call.applications.stop(machine.to_sym, id)
|
224
181
|
end
|
225
|
-
|
226
|
-
private
|
227
|
-
|
228
|
-
def find_app(machine ,id)
|
229
|
-
apps = client.call.applications.all(machine.to_sym).last || []
|
230
|
-
app = apps.detect do |app|
|
231
|
-
app[1] == id
|
232
|
-
end
|
233
|
-
|
234
|
-
unless app
|
235
|
-
puts ui.color('Application not found!', :red)
|
236
|
-
exit(1)
|
237
|
-
end
|
238
|
-
|
239
|
-
app
|
240
|
-
end
|
241
|
-
|
242
|
-
def show_app(app)
|
243
|
-
app = app.to_a.dup
|
244
|
-
app.shift
|
245
|
-
app.pop
|
246
|
-
app.collect! do |v|
|
247
|
-
case v
|
248
|
-
when Array then v.join(', ')
|
249
|
-
else v.to_s
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
ui.table %w( Id Machine Name Domains Environment User Group Root Installed\ Gems Requested\ Gems ), app, :columns_down, 2
|
254
|
-
end
|
255
|
-
|
182
|
+
|
256
183
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Capricorn::CLI::ApplicationsDomains < Capricorn::CLI
|
2
|
+
|
3
|
+
include Capricorn::Helpers
|
4
|
+
|
5
|
+
namespace "apps:domains"
|
6
|
+
|
7
|
+
desc "list", "list all domains"
|
8
|
+
def list
|
9
|
+
application_info[4].sort! do |a, b|
|
10
|
+
a <=> b
|
11
|
+
end
|
12
|
+
application_info[4].each do |domain|
|
13
|
+
puts "- #{domain}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "add DOMAIN", "add a new domain"
|
18
|
+
def add(domain)
|
19
|
+
domain = domain.strip.sub(/^www\./, '')
|
20
|
+
|
21
|
+
begin
|
22
|
+
domain = PublicSuffixService.parse(domain).to_s
|
23
|
+
rescue Exception
|
24
|
+
halt "invalid domain: #{domain}"
|
25
|
+
end
|
26
|
+
|
27
|
+
machine, id = *application
|
28
|
+
app = application_info
|
29
|
+
|
30
|
+
if app[4].include?(domain)
|
31
|
+
halt "Domain is already configured"
|
32
|
+
end
|
33
|
+
|
34
|
+
app[4].push(domain)
|
35
|
+
|
36
|
+
p client.call.applications.update(machine.to_sym, id, app[4], app[10])
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "remove DOMAIN", "remove a domain"
|
40
|
+
def remove(domain)
|
41
|
+
domain = domain.strip.sub(/^www\./, '')
|
42
|
+
|
43
|
+
begin
|
44
|
+
domain = PublicSuffixService.parse(domain).to_s
|
45
|
+
rescue Exception
|
46
|
+
halt "invalid domain: #{domain}"
|
47
|
+
end
|
48
|
+
|
49
|
+
machine, id = *application
|
50
|
+
app = application_info
|
51
|
+
|
52
|
+
unless app[4].include?(domain)
|
53
|
+
halt "Domain is not configured"
|
54
|
+
end
|
55
|
+
|
56
|
+
app[4].delete(domain)
|
57
|
+
|
58
|
+
p client.call.applications.update(machine.to_sym, id, app[4], app[10])
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Capricorn::CLI::ApplicationsGems < Capricorn::CLI
|
2
|
+
|
3
|
+
include Capricorn::Helpers
|
4
|
+
|
5
|
+
namespace "apps:gems"
|
6
|
+
|
7
|
+
desc "list", "list all gems"
|
8
|
+
def list
|
9
|
+
application_info[9].sort! do |a,b|
|
10
|
+
a[1] <=> b[1]
|
11
|
+
end
|
12
|
+
|
13
|
+
application_info[10].sort! do |a,b|
|
14
|
+
a <=> b
|
15
|
+
end
|
16
|
+
|
17
|
+
puts "Configured gems:"
|
18
|
+
application_info[10].each do |name|
|
19
|
+
puts "- #{name}"
|
20
|
+
end
|
21
|
+
puts
|
22
|
+
|
23
|
+
puts "Used gems:"
|
24
|
+
application_info[9].each do |gem|
|
25
|
+
puts "- #{gem[1]} (#{gem[2].flatten.join('.')})"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "add GEM_NAME", "add a new gem"
|
30
|
+
def add(gem_name)
|
31
|
+
gem_name = gem_name.strip
|
32
|
+
|
33
|
+
machine, id = *application
|
34
|
+
app = application_info
|
35
|
+
|
36
|
+
if app[10].include?(gem_name)
|
37
|
+
halt "Gem is already configured"
|
38
|
+
end
|
39
|
+
|
40
|
+
app[10].push(gem_name)
|
41
|
+
|
42
|
+
p client.call.applications.update(machine.to_sym, id, app[4], app[10])
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "remove GEM_NAME", "remove a gem"
|
46
|
+
def remove(gem_name)
|
47
|
+
gem_name = gem_name.strip
|
48
|
+
|
49
|
+
machine, id = *application
|
50
|
+
app = application_info
|
51
|
+
|
52
|
+
unless app[10].include?(gem_name)
|
53
|
+
halt "Gem is not configured"
|
54
|
+
end
|
55
|
+
|
56
|
+
app[10].delete(gem_name)
|
57
|
+
|
58
|
+
p client.call.applications.update(machine.to_sym, id, app[4], app[10])
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -1,45 +1,67 @@
|
|
1
|
-
class Capricorn::CLI::Gems <
|
1
|
+
class Capricorn::CLI::Gems < Capricorn::CLI
|
2
2
|
include Capricorn::Helpers
|
3
|
-
|
3
|
+
|
4
|
+
namespace :gems
|
5
|
+
|
4
6
|
desc "push PATHS...", "push gems to capricorn"
|
5
7
|
def push(*paths)
|
6
8
|
paths = paths.flatten.collect do |path|
|
7
9
|
Dir.glob(path)
|
8
10
|
end.flatten
|
11
|
+
|
9
12
|
paths.each do |path|
|
10
13
|
begin
|
11
14
|
client.call(:stream => path).gems.push
|
12
|
-
|
15
|
+
info "Pushed: #{File.basename(path)}"
|
13
16
|
rescue BERTRPC::UserError => e
|
14
|
-
|
17
|
+
halt(e.message, $capr_gems_weak_push)
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
18
|
-
|
21
|
+
|
19
22
|
desc "missing", "list missing gems"
|
20
23
|
def missing
|
21
|
-
|
24
|
+
all = clean_missing(client.call.gems.missing)
|
25
|
+
all.sort! { |a, b| a[0] <=> b[0] }
|
26
|
+
width = all.inject(0) { |m, (name, _)| (m > name.size ? m : name.size) }
|
27
|
+
all.each do |(name, versions)|
|
28
|
+
padding = ' ' * (width - name.size)
|
29
|
+
puts "#{padding}#{name}: #{versions}"
|
30
|
+
end
|
22
31
|
end
|
23
|
-
|
32
|
+
|
24
33
|
desc "all", "list all gems"
|
25
34
|
def all
|
26
|
-
|
35
|
+
all = clean_all(client.call.gems.all)
|
36
|
+
all.sort! { |a, b| a[0] <=> b[0] }
|
37
|
+
width = all.inject(0) { |m, (name, _)| (m > name.size ? m : name.size) }
|
38
|
+
all.each do |(name, versions)|
|
39
|
+
padding = ' ' * (width - name.size)
|
40
|
+
puts "#{padding}#{name}: #{versions}"
|
41
|
+
end
|
27
42
|
end
|
28
|
-
|
43
|
+
|
29
44
|
private
|
30
|
-
|
45
|
+
|
31
46
|
def clean_all(gems)
|
32
47
|
gems = gems.last
|
33
48
|
gems.inject(Hash.new { |h,k| h[k] = [] }) do |m, g|
|
34
49
|
header, name, version = *(g.to_ary)
|
50
|
+
next(m) unless version.last
|
35
51
|
version = version.last.join('.')
|
36
52
|
m[name.to_s] << version
|
37
53
|
m
|
38
54
|
end.collect do |name, versions|
|
39
|
-
|
40
|
-
|
55
|
+
versions = versions.reverse
|
56
|
+
if versions.size > 5
|
57
|
+
versions = versions[0, 5].join(', ') + ", (and #{versions.size - 5} more)"
|
58
|
+
else
|
59
|
+
versions = versions.join(', ')
|
60
|
+
end
|
61
|
+
[name, versions]
|
62
|
+
end
|
41
63
|
end
|
42
|
-
|
64
|
+
|
43
65
|
def clean_missing(deps)
|
44
66
|
deps = deps.last if deps and deps.first == :ok
|
45
67
|
return [] if deps.nil? or deps.empty?
|
@@ -49,9 +71,9 @@ private
|
|
49
71
|
op = req.shift
|
50
72
|
version = req.shift.to_a.last.join('.')
|
51
73
|
"#{op} #{version}"
|
52
|
-
end.join(', ')
|
74
|
+
end.reverse.join(', ')
|
53
75
|
[dep.first, reqs]
|
54
|
-
end
|
76
|
+
end
|
55
77
|
end
|
56
|
-
|
78
|
+
|
57
79
|
end
|
@@ -1,20 +1,29 @@
|
|
1
|
-
class Capricorn::CLI::Machines <
|
1
|
+
class Capricorn::CLI::Machines < Capricorn::CLI
|
2
2
|
include Capricorn::Helpers
|
3
3
|
|
4
|
+
namespace :machines
|
5
|
+
|
4
6
|
desc "list", "list all machines"
|
5
7
|
def list
|
6
|
-
|
8
|
+
machines.sort! do |a, b|
|
9
|
+
a <=> b
|
10
|
+
end
|
11
|
+
|
12
|
+
puts "Machines:"
|
13
|
+
machines.each do |machine|
|
14
|
+
puts "- #{machine}"
|
15
|
+
end
|
7
16
|
end
|
8
17
|
|
9
|
-
desc "reboot
|
10
|
-
|
11
|
-
|
18
|
+
desc "reboot", "reboot a node"
|
19
|
+
method_option :node, :type => :string
|
20
|
+
def reboot
|
12
21
|
puts client.call.runtime.reboot(node.to_sym)
|
13
22
|
end
|
14
23
|
|
15
|
-
desc "selfupdate
|
16
|
-
|
17
|
-
|
24
|
+
desc "selfupdate", "update a node"
|
25
|
+
method_option :node, :type => :string
|
26
|
+
def selfupdate
|
18
27
|
puts client.call.runtime.selfupdate(node.to_sym)
|
19
28
|
end
|
20
29
|
|
@@ -1,43 +1,28 @@
|
|
1
1
|
module Capricorn::Helpers
|
2
2
|
|
3
|
-
|
4
|
-
if self.machines.size > 1
|
5
|
-
ui.choose(*self.machines)
|
6
|
-
elsif self.machines.size == 1 and ui.agree("Use machine #{self.machines.first}? ")
|
7
|
-
self.machines.first
|
8
|
-
else
|
9
|
-
puts ui.color('No machines found!!!', :red)
|
10
|
-
exit(1)
|
11
|
-
end
|
12
|
-
end
|
3
|
+
require 'abbrev'
|
13
4
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
5
|
+
DEFAULT_CONFIG = <<-EOH
|
6
|
+
cluster_name:
|
7
|
+
host: localhost
|
8
|
+
port: 3457
|
9
|
+
username: dummy
|
10
|
+
password: dummy
|
11
|
+
EOH
|
12
|
+
|
13
|
+
def application_ids
|
14
|
+
@application_ids ||= begin
|
15
|
+
apps = applications.collect do |app|
|
16
|
+
app[1]
|
17
|
+
end
|
18
|
+
apps.flatten!
|
19
|
+
apps
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
apps = client.call.applications.all(machine.to_sym).last || []
|
29
|
-
apps.collect! do |app|
|
30
|
-
app[1]
|
31
|
-
end
|
32
|
-
apps.flatten!
|
33
|
-
|
34
|
-
if apps.size > 1
|
35
|
-
[machine, ui.choose(*apps)]
|
36
|
-
elsif apps.size == 1 and ui.agree("Use application #{apps.first}? ")
|
37
|
-
[machine, apps.first]
|
38
|
-
else
|
39
|
-
puts ui.color('No application found!!!', :red)
|
40
|
-
exit(1)
|
23
|
+
def applications
|
24
|
+
@applications ||= begin
|
25
|
+
client.call.applications.all(machine.to_sym).last || []
|
41
26
|
end
|
42
27
|
end
|
43
28
|
|
@@ -53,27 +38,188 @@ module Capricorn::Helpers
|
|
53
38
|
end
|
54
39
|
end
|
55
40
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
41
|
+
def application_info
|
42
|
+
@application_info ||= begin
|
43
|
+
apps = applications
|
44
|
+
app = apps.detect do |app|
|
45
|
+
app[1] == application.last
|
46
|
+
end
|
47
|
+
|
48
|
+
unless app
|
49
|
+
halt 'Application not found!'
|
50
|
+
end
|
51
|
+
|
52
|
+
app
|
53
|
+
end
|
61
54
|
end
|
62
55
|
|
63
|
-
def
|
64
|
-
@
|
65
|
-
|
66
|
-
|
67
|
-
|
56
|
+
def application
|
57
|
+
@application ||= begin
|
58
|
+
application = nil
|
59
|
+
if options.application
|
60
|
+
application = options.application
|
61
|
+
elsif environment['application']
|
62
|
+
application = environment['application']
|
63
|
+
elsif application_ids.size == 1
|
64
|
+
application = application_ids.first
|
65
|
+
info "Selected default application: #{application}"
|
66
|
+
else
|
67
|
+
halt "Please select a application!"
|
68
|
+
end
|
69
|
+
|
70
|
+
if application
|
71
|
+
application = application_ids.abbrev[application]
|
72
|
+
end
|
73
|
+
|
74
|
+
unless application_ids.include?(application)
|
75
|
+
halt "I don't know this application!"
|
76
|
+
end
|
77
|
+
|
78
|
+
[machine, application]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def machine
|
83
|
+
@machine ||= begin
|
84
|
+
machine = nil
|
85
|
+
if options.machine
|
86
|
+
machine = options.machine
|
87
|
+
elsif environment['machine']
|
88
|
+
machine = environment['machine']
|
89
|
+
elsif machines.size == 1
|
90
|
+
machine = machines.first
|
91
|
+
info "Selected default machine: #{machine}"
|
92
|
+
else
|
93
|
+
halt "Please select a machine!"
|
94
|
+
end
|
95
|
+
|
96
|
+
if machine
|
97
|
+
machine = machines.abbrev[machine]
|
98
|
+
end
|
99
|
+
|
100
|
+
unless machines.include?(machine)
|
101
|
+
halt "I don't know this machine!"
|
102
|
+
end
|
103
|
+
|
104
|
+
machine
|
68
105
|
end
|
69
106
|
end
|
70
107
|
|
71
|
-
|
108
|
+
def node
|
109
|
+
@node ||= begin
|
110
|
+
node = nil
|
111
|
+
if options.machine
|
112
|
+
node = options.machine
|
113
|
+
elsif environment['machine']
|
114
|
+
node = environment['machine']
|
115
|
+
elsif nodes.size == 1
|
116
|
+
node = nodes.first
|
117
|
+
info "Selected default node: #{node}"
|
118
|
+
else
|
119
|
+
halt "Please select a node!"
|
120
|
+
end
|
121
|
+
|
122
|
+
if node
|
123
|
+
node = nodes.abbrev[node]
|
124
|
+
end
|
72
125
|
|
73
|
-
|
74
|
-
|
75
|
-
|
126
|
+
unless nodes.include?(node)
|
127
|
+
halt "I don't know this node!"
|
128
|
+
end
|
129
|
+
|
130
|
+
node
|
76
131
|
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def cluster
|
135
|
+
@cluster ||= begin
|
136
|
+
cluster = nil
|
137
|
+
if options.cluster
|
138
|
+
cluster = options.cluster
|
139
|
+
elsif environment['cluster']
|
140
|
+
cluster = environment['cluster']
|
141
|
+
elsif config.size == 1
|
142
|
+
cluster = config.keys.first
|
143
|
+
info "Selected default cluster: #{cluster}"
|
144
|
+
else
|
145
|
+
halt "Please select a cluster!"
|
146
|
+
end
|
147
|
+
|
148
|
+
if cluster
|
149
|
+
cluster = config.keys.abbrev[cluster]
|
150
|
+
end
|
151
|
+
|
152
|
+
unless config.keys.include?(cluster)
|
153
|
+
halt "I don't know this cluster!"
|
154
|
+
end
|
155
|
+
|
156
|
+
config[cluster]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def environment
|
161
|
+
@environment ||= begin
|
162
|
+
environment = nil
|
163
|
+
if options.environment
|
164
|
+
environment = options.environment
|
165
|
+
elsif local_config.size == 1
|
166
|
+
environment = local_config.keys.first
|
167
|
+
info "Selected default environment: #{environment}"
|
168
|
+
elsif local_config.size > 1
|
169
|
+
halt "Please select an environment!"
|
170
|
+
end
|
171
|
+
|
172
|
+
if environment
|
173
|
+
environment = local_config.keys.abbrev[environment]
|
174
|
+
end
|
175
|
+
|
176
|
+
config = nil
|
177
|
+
if environment.nil?
|
178
|
+
config = {}
|
179
|
+
elsif local_config.keys.include?(environment)
|
180
|
+
config = local_config[environment]
|
181
|
+
else
|
182
|
+
halt "I don't know this environment!"
|
183
|
+
end
|
184
|
+
config
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def local_config
|
189
|
+
@local_config ||= begin
|
190
|
+
if File.file?('.capricorn.yml')
|
191
|
+
YAML.load_file('.capricorn.yml')
|
192
|
+
else
|
193
|
+
{}
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def config
|
199
|
+
@config ||= begin
|
200
|
+
config_path = File.expand_path('~/.capricorn/config.yml')
|
201
|
+
unless File.file?(config_path)
|
202
|
+
FileUtils.mkdir_p(File.dirname(config_path))
|
203
|
+
File.open(config_path, 'w+', 0600) { |file| file.write DEFAULT_CONFIG }
|
204
|
+
info "Please edit your config file in ~/.capricorn/config.yml"
|
205
|
+
exit 2
|
206
|
+
end
|
207
|
+
YAML.load_file(config_path)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def client
|
212
|
+
host = (cluster['host'] || 'localhost').to_s
|
213
|
+
port = (cluster['port'] || 3457).to_i
|
214
|
+
@client ||= BERTRPC::Service.new(host, port)
|
215
|
+
end
|
216
|
+
|
217
|
+
def info(msg)
|
218
|
+
shell.say_status('Info', msg)
|
219
|
+
end
|
77
220
|
|
221
|
+
def halt(msg, continue=false)
|
222
|
+
shell.say_status('Error', msg, :red)
|
223
|
+
exit(1) unless continue
|
78
224
|
end
|
79
225
|
end
|
data/lib/capricorn/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capricorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 2.0.
|
9
|
+
- 7
|
10
|
+
version: 2.0.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Simon Menke
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-06-
|
18
|
+
date: 2010-06-11 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -35,83 +35,83 @@ dependencies:
|
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
38
|
+
name: mustache
|
39
39
|
prerelease: false
|
40
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - "="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
45
|
+
hash: 9
|
46
46
|
segments:
|
47
|
-
-
|
47
|
+
- 0
|
48
48
|
- 5
|
49
|
-
-
|
50
|
-
version:
|
49
|
+
- 1
|
50
|
+
version: 0.5.1
|
51
51
|
type: :runtime
|
52
52
|
version_requirements: *id002
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
|
-
name:
|
54
|
+
name: rush
|
55
55
|
prerelease: false
|
56
56
|
requirement: &id003 !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
59
|
- - "="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
hash:
|
61
|
+
hash: 13
|
62
62
|
segments:
|
63
63
|
- 0
|
64
|
+
- 6
|
64
65
|
- 5
|
65
|
-
|
66
|
-
version: 0.5.1
|
66
|
+
version: 0.6.5
|
67
67
|
type: :runtime
|
68
68
|
version_requirements: *id003
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: session
|
71
71
|
prerelease: false
|
72
72
|
requirement: &id004 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - "="
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
hash:
|
77
|
+
hash: 3
|
78
78
|
segments:
|
79
|
+
- 3
|
80
|
+
- 1
|
79
81
|
- 0
|
80
|
-
|
81
|
-
- 5
|
82
|
-
version: 0.6.5
|
82
|
+
version: 3.1.0
|
83
83
|
type: :runtime
|
84
84
|
version_requirements: *id004
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
|
-
name:
|
86
|
+
name: thor
|
87
87
|
prerelease: false
|
88
88
|
requirement: &id005 !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
91
91
|
- - "="
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
hash:
|
93
|
+
hash: 39
|
94
94
|
segments:
|
95
|
-
- 3
|
96
|
-
- 1
|
97
95
|
- 0
|
98
|
-
|
96
|
+
- 13
|
97
|
+
- 6
|
98
|
+
version: 0.13.6
|
99
99
|
type: :runtime
|
100
100
|
version_requirements: *id005
|
101
101
|
- !ruby/object:Gem::Dependency
|
102
|
-
name:
|
102
|
+
name: public_suffix_service
|
103
103
|
prerelease: false
|
104
104
|
requirement: &id006 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - "="
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
hash:
|
109
|
+
hash: 15
|
110
110
|
segments:
|
111
111
|
- 0
|
112
|
-
-
|
113
|
-
-
|
114
|
-
version: 0.
|
112
|
+
- 4
|
113
|
+
- 0
|
114
|
+
version: 0.4.0
|
115
115
|
type: :runtime
|
116
116
|
version_requirements: *id006
|
117
117
|
description: Build, manage and configure many railsish web applications.
|
@@ -134,6 +134,8 @@ files:
|
|
134
134
|
- lib/capricorn/recipes/macports.rb
|
135
135
|
- lib/capricorn/system_context.rb
|
136
136
|
- lib/capricorn/version.rb
|
137
|
+
- lib/capricorn-client/cli/applications/domains.rb
|
138
|
+
- lib/capricorn-client/cli/applications/gems.rb
|
137
139
|
- lib/capricorn-client/cli/applications.rb
|
138
140
|
- lib/capricorn-client/cli/gems.rb
|
139
141
|
- lib/capricorn-client/cli/machines.rb
|