capricorn 2.0.6 → 2.0.7

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.
@@ -7,4 +7,4 @@ rescue LoadError
7
7
  require 'capricorn-client'
8
8
  end
9
9
 
10
- Capricorn::Runner.start
10
+ Capricorn::CLI.start
@@ -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
- module CLI
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
- @cluster = config[cluster_name]
46
- unless @cluster
47
- puts "I don't know this cluster"
48
- exit 1
49
- end
18
+ def self.banner(task)
19
+ "#{banner_base} #{task.formatted_usage(self, true)}"
20
+ end
50
21
 
51
- case ARGV.shift
52
- when 'applications'
53
- Capricorn::CLI::Applications.start
54
- when 'gems'
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
- help
27
+ super
60
28
  end
61
29
  end
62
30
 
63
- def help
64
- puts HELP
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
- def cluster
68
- @cluster
69
- end
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
- def config
72
- @config ||= begin
73
- config_path = File.expand_path('~/.capricorn/config.yml')
74
- unless File.file?(config_path)
75
- FileUtils.mkdir_p(File.dirname(config_path))
76
- File.open(config_path, 'w+', 0600) { |file| file.write DEFAULT_CONFIG }
77
- puts "Please edit your config file in ~/.capricorn/config.yml"
78
- exit 2
79
- end
80
- YAML.load_file(config_path)
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 < Thor
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[1], app[3]]
30
+ [app[3], app[1]]
11
31
  end
12
- apps.flatten!
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
- environment = ui.choose do |q|
31
- q.choices(*%w( production development staging testing ))
32
- q.prompt = "environment: "
33
- q.default = 'production'
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
- domains = []
36
- domains << ui.ask("domain: ") do |q|
37
- q.validate = /^[\w\d]+(\.[\w\d]+)*$/
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
- loop do
40
- domain = ui.ask("more: ") do |q|
41
- q.validate = /^([\w\d]+(\.[\w\d]+)*)?$/
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
- break if domain.strip.empty?
44
- domains << domain
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
- puts ui.color('This doesn\'t appear to be a milkshake app!', :red)
62
- puts ui.color('no milkshake config was found', :red)
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
- puts ui.color('This doesn\'t appear to be a milkshake app!', :red)
68
- puts ui.color('no shared dir was found', :red)
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
- puts ui.color('This doesn\'t appear to be a milkshake app!', :red)
76
- puts ui.color('no gems were found', :red)
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
- puts ui.color('This doesn\'t appear to be a milkshake app!', :red)
83
- puts ui.color('no environment.rb was found', :red)
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
- puts ui.color('This doesn\'t appear to be a milkshake app!', :red)
90
- puts ui.color('no uid was found', :red)
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
- puts ui.color('This doesn\'t appear to be a milkshake app!', :red)
97
- puts ui.color('no gid was found', :red)
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
- domains = []
111
- domains << ui.ask("domain: ") do |q|
112
- q.validate = /^[\w\d]+(\.[\w\d]+)*$/
123
+
124
+ name = name.to_s.strip
125
+ if name.empty?
126
+ halt "Please choose a name!"
113
127
  end
114
- loop do
115
- domain = ui.ask("more: ") do |q|
116
- q.validate = /^([\w\d]+(\.[\w\d]+)*)?$/
117
- end
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
- p client.call.applications.import(machine.to_sym, name, domains, environment, root, gems, uid, gid)
129
- end
130
-
131
- desc "update", "update an application on MACHINE"
132
- def update
133
- machine, id = *select_application
134
- app = find_app(machine, id)
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 = *select_application
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 = *select_application
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 = *select_application
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 = *select_application
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 = *select_application
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 < Thor
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
- puts ui.color("Pushed: #{File.basename(path)}", :green)
15
+ info "Pushed: #{File.basename(path)}"
13
16
  rescue BERTRPC::UserError => e
14
- puts ui.color(e.message, :red)
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
- ui.table %w( Gem Requirements ), clean_missing(client.call.gems.missing), :columns_across, 2
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
- ui.table %w( Gem Versions ), clean_all(client.call.gems.all), :columns_across, 2
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
- [name, versions.join(', ')]
40
- end.flatten
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.flatten
76
+ end
55
77
  end
56
-
78
+
57
79
  end
@@ -1,20 +1,29 @@
1
- class Capricorn::CLI::Machines < Thor
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
- ui.table("Machines", self.machines)
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 [NODE]", "reboot a node"
10
- def reboot(node=nil)
11
- node ||= select_node
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 [NODE]", "update a node"
16
- def selfupdate(node=nil)
17
- node ||= select_node
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
- def select_machine
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
- def select_node
15
- if self.nodes.size > 1
16
- ui.choose(*self.nodes)
17
- elsif self.nodes.size == 1 and ui.agree("Use nodes #{self.nodes.first}? ")
18
- self.nodes.first
19
- else
20
- puts ui.color('No nodes found!!!', :red)
21
- exit(1)
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 select_application
26
- machine = select_machine
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 client
57
- cluster = Capricorn::Runner.cluster
58
- host = (cluster['host'] || 'localhost').to_s
59
- port = (cluster['port'] || 3457).to_i
60
- @client ||= BERTRPC::Service.new(host, port)
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 ui
64
- @ui ||= begin
65
- @ui = HighLine.new
66
- @ui.extend UI
67
- @ui
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
- module UI
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
- def table(headers, items, mode=:rows, option=nil)
74
- headers = [headers].flatten.collect { |h| color(h, :green) }
75
- @output.puts list(headers+items, mode, option)
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
@@ -1,5 +1,5 @@
1
1
  module Capricorn
2
2
 
3
- VERSION = '2.0.6'
3
+ VERSION = '2.0.7'
4
4
 
5
5
  end
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: 3
4
+ hash: 1
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
- - 6
10
- version: 2.0.6
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-10 00:00:00 +02:00
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: highline
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: 7
45
+ hash: 9
46
46
  segments:
47
- - 1
47
+ - 0
48
48
  - 5
49
- - 2
50
- version: 1.5.2
49
+ - 1
50
+ version: 0.5.1
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
54
- name: mustache
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: 9
61
+ hash: 13
62
62
  segments:
63
63
  - 0
64
+ - 6
64
65
  - 5
65
- - 1
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: rush
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: 13
77
+ hash: 3
78
78
  segments:
79
+ - 3
80
+ - 1
79
81
  - 0
80
- - 6
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: session
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: 3
93
+ hash: 39
94
94
  segments:
95
- - 3
96
- - 1
97
95
  - 0
98
- version: 3.1.0
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: thor
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: 41
109
+ hash: 15
110
110
  segments:
111
111
  - 0
112
- - 12
113
- - 3
114
- version: 0.12.3
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