lib/gaptool-client.rb in gaptool-client-0.7.1 vs lib/gaptool-client.rb in gaptool-client-0.7.2
- old
+ new
@@ -4,10 +4,11 @@
require 'peach'
require 'json'
require 'clamp'
require 'net/ssh'
require 'net/scp'
+require 'set'
def infohelper(nodes, parseable, grepable)
if parseable
puts nodes.to_json
else
@@ -312,34 +313,62 @@
end
end
end
class DeployCommand < Clamp::Command
- option ["-a", "--app"], "APP", "Application to deploy", :required => true
+ option ["-a", "--app"], "APP", "Application(s) to deploy (can be set multiple times)", :required => true, :multivalued => true
option ["-m", "--migrate"], :flag, "Toggle running migrations"
option ["-e", "--environment"], "ENVIRONMENT", "Which environment, e.g. production", :required => true
option ["-b", "--branch"], "BRANCH", "Git branch to deploy, default is master", :required => false
option ["-r", "--rollback"], :flag, "Toggle this to rollback last deploy"
- option ["-i", "--instance"], "INSTANCE", "Instance ID, e.g. i-12345678", :required => false
+ option ["-i", "--instance"], "INSTANCE", "Instance ID, e.g. i-12345678. If set, all applications MUST be hosted on this node.", :required => false
option ["-A", "--attribute"], "ATTRIBUTE", "Pass one or more parameters to the deploy recipe in recipe.attr=value format", :multivalued => true
option ['-H', '--hidden'], :flag, 'Display hidden hosts'
def execute
attrs = split_attrs(attribute_list)
if instance
n = $api.getonenode(instance)
if n['environment'] != environment
abort "Instance #{instance} is not in environment #{environment}"
- elsif !n['apps'].include?(app)
- abort "Instance #{instance} does not host #{app} in env #{environment}"
+ else
+ app_list.each do |app|
+ if !n['apps'].include?(app)
+ abort "Instance #{instance} does not host #{app} in env #{environment}"
+ end
+ end
end
nodes = [n]
+
else
params = hidden? ? {hidden: true} : {}
- nodes = $api.getappnodes(app, environment, params)
+ nodes = []
+ app_list.each do |app|
+ nodes.concat($api.getappnodes(app, environment, params))
+ end
end
+
+ # dedup nodes
+ seen = Set.new
+ app_set = Set.new(app_list)
+ nodes = nodes.select do |x|
+ res = !seen.include?(x['instance']);
+ seen << x['instance'];
+ res
+ end.map do |x|
+ x['apps'] = eval(x['apps'])
+ x['apps_to_deploy'] = (Set.new(x['apps']) & app_set).to_a
+ x
+ end
+
nodes.peach do |node|
+ host = "#{node['role']}:#{node['environment']}:#{node['instance']}"
+ puts "#{Rainbow("Deploying apps").cyan} '" + \
+ Rainbow(node['apps_to_deploy'].join(" ")).green + \
+ "' #{Rainbow("on").cyan} " + \
+ Rainbow(host).green
+
if node['chef_runlist'].nil?
runlist = ['recipe[deploy]']
elsif node['chef_runlist'].is_a? Array
runlist = node['chef_runlist']
else
@@ -353,12 +382,11 @@
'run_list' => runlist,
'hostname' => node['hostname'],
'instance' => node['instance'],
'zone' => node['zone'],
'itype' => node['itype'],
- 'apps' => eval(node['apps']),
- 'app_name' => app,
- 'app' => app,
+ 'apps' => node['apps'],
+ 'deploy_apps' => node['apps_to_deploy'],
'rollback' => rollback?,
'branch' => branch || 'master',
'migrate' => migrate?
}.merge(attrs).to_json
commands = [