ironfan 3.2.2 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/VERSION +1 -1
- data/ironfan.gemspec +33 -20
- data/lib/chef/knife/cluster_kick.rb +17 -17
- data/lib/chef/knife/cluster_kill.rb +13 -7
- data/lib/chef/knife/cluster_launch.rb +60 -66
- data/lib/chef/knife/cluster_pry.rb +2 -2
- data/lib/chef/knife/cluster_show.rb +3 -6
- data/lib/chef/knife/cluster_ssh.rb +5 -11
- data/lib/chef/knife/cluster_start.rb +2 -4
- data/lib/chef/knife/cluster_stop.rb +1 -3
- data/lib/chef/knife/cluster_sync.rb +13 -21
- data/lib/chef/knife/ironfan_knife_common.rb +11 -9
- data/lib/chef/knife/ironfan_script.rb +2 -1
- data/lib/gorillib/resolution.rb +119 -0
- data/lib/ironfan/broker/computer.rb +316 -0
- data/lib/ironfan/broker/drive.rb +21 -0
- data/lib/ironfan/broker.rb +37 -0
- data/lib/ironfan/builder.rb +14 -0
- data/lib/ironfan/deprecated.rb +16 -58
- data/lib/ironfan/dsl/cloud.rb +21 -0
- data/lib/ironfan/dsl/cluster.rb +27 -0
- data/lib/ironfan/dsl/compute.rb +84 -0
- data/lib/ironfan/dsl/ec2.rb +260 -0
- data/lib/ironfan/dsl/facet.rb +25 -0
- data/lib/ironfan/dsl/role.rb +19 -0
- data/lib/ironfan/dsl/server.rb +31 -0
- data/lib/ironfan/dsl/virtualbox.rb +8 -0
- data/lib/ironfan/dsl/volume.rb +45 -0
- data/lib/ironfan/dsl.rb +7 -0
- data/lib/ironfan/headers.rb +58 -0
- data/lib/ironfan/provider/chef/client.rb +77 -0
- data/lib/ironfan/provider/chef/node.rb +133 -0
- data/lib/ironfan/provider/chef/role.rb +69 -0
- data/lib/ironfan/provider/chef.rb +28 -0
- data/lib/ironfan/provider/ec2/ebs_volume.rb +137 -0
- data/lib/ironfan/provider/ec2/elastic_ip.rb +10 -0
- data/lib/ironfan/provider/ec2/key_pair.rb +65 -0
- data/lib/ironfan/provider/ec2/machine.rb +258 -0
- data/lib/ironfan/provider/ec2/placement_group.rb +24 -0
- data/lib/ironfan/provider/ec2/security_group.rb +118 -0
- data/lib/ironfan/provider/ec2.rb +47 -0
- data/lib/ironfan/provider/virtualbox/machine.rb +10 -0
- data/lib/ironfan/provider/virtualbox.rb +8 -0
- data/lib/ironfan/provider.rb +139 -0
- data/lib/ironfan/requirements.rb +52 -0
- data/lib/ironfan.rb +44 -33
- metadata +34 -21
- data/lib/chef/knife/cluster_vagrant.rb +0 -144
- data/lib/chef/knife/vagrant/ironfan_environment.rb +0 -18
- data/lib/chef/knife/vagrant/ironfan_provisioners.rb +0 -27
- data/lib/chef/knife/vagrant/skeleton_vagrantfile.rb +0 -119
- data/lib/ironfan/chef_layer.rb +0 -300
- data/lib/ironfan/cloud.rb +0 -323
- data/lib/ironfan/cluster.rb +0 -118
- data/lib/ironfan/compute.rb +0 -139
- data/lib/ironfan/discovery.rb +0 -190
- data/lib/ironfan/dsl_builder.rb +0 -99
- data/lib/ironfan/facet.rb +0 -143
- data/lib/ironfan/fog_layer.rb +0 -196
- data/lib/ironfan/private_key.rb +0 -130
- data/lib/ironfan/role_implications.rb +0 -58
- data/lib/ironfan/security_group.rb +0 -133
- data/lib/ironfan/server.rb +0 -291
- data/lib/ironfan/server_slice.rb +0 -265
- data/lib/ironfan/volume.rb +0 -146
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# v4.0.0: Major refactoring to allow multicloud support
|
2
|
+
* First pass at a provider plugin API, with EC2 as the working example.
|
3
|
+
* Removed role_implications: these can be handled by explicit ec2.security_group calls for now. See https://github.com/infochimps-labs/ironfan/wiki/Upgrading-to-v4 for more details.
|
4
|
+
* Added default_cloud flag to cloud statement (sets that cloud as the default one, if there are multiple clouds available), added use_cloud statement to compute components (cluster/facet/server) which overrides those defaults. There are plans for a command-line override, as well.
|
5
|
+
|
1
6
|
# v3.2.0: First refactoring pass in preparation for multi-cloud support
|
2
7
|
* Rebuilt the internal models of Ironfan to use gorillib's Field/Model/Builder architecture.
|
3
8
|
* [#145](https://github.com/infochimps-labs/ironfan/pull/145): node attribues should be 'normal', not 'override' -- they don't show up as printed on the node otherwise
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4.0.0
|
data/ironfan.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "ironfan"
|
8
|
-
s.version = "
|
8
|
+
s.version = "4.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Infochimps"]
|
12
|
-
s.date = "2012-09-
|
12
|
+
s.date = "2012-09-06"
|
13
13
|
s.description = "Ironfan allows you to orchestrate not just systems but clusters of machines. It includes a powerful layer on top of knife and a collection of cloud cookbooks."
|
14
14
|
s.email = "coders@infochimps.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -49,28 +49,41 @@ Gem::Specification.new do |s|
|
|
49
49
|
"lib/chef/knife/cluster_start.rb",
|
50
50
|
"lib/chef/knife/cluster_stop.rb",
|
51
51
|
"lib/chef/knife/cluster_sync.rb",
|
52
|
-
"lib/chef/knife/cluster_vagrant.rb",
|
53
52
|
"lib/chef/knife/ironfan_knife_common.rb",
|
54
53
|
"lib/chef/knife/ironfan_script.rb",
|
55
|
-
"lib/
|
56
|
-
"lib/chef/knife/vagrant/ironfan_provisioners.rb",
|
57
|
-
"lib/chef/knife/vagrant/skeleton_vagrantfile.rb",
|
54
|
+
"lib/gorillib/resolution.rb",
|
58
55
|
"lib/ironfan.rb",
|
59
|
-
"lib/ironfan/
|
60
|
-
"lib/ironfan/
|
61
|
-
"lib/ironfan/
|
62
|
-
"lib/ironfan/
|
56
|
+
"lib/ironfan/broker.rb",
|
57
|
+
"lib/ironfan/broker/computer.rb",
|
58
|
+
"lib/ironfan/broker/drive.rb",
|
59
|
+
"lib/ironfan/builder.rb",
|
63
60
|
"lib/ironfan/deprecated.rb",
|
64
|
-
"lib/ironfan/
|
65
|
-
"lib/ironfan/
|
66
|
-
"lib/ironfan/
|
67
|
-
"lib/ironfan/
|
68
|
-
"lib/ironfan/
|
69
|
-
"lib/ironfan/
|
70
|
-
"lib/ironfan/
|
71
|
-
"lib/ironfan/server.rb",
|
72
|
-
"lib/ironfan/
|
73
|
-
"lib/ironfan/volume.rb",
|
61
|
+
"lib/ironfan/dsl.rb",
|
62
|
+
"lib/ironfan/dsl/cloud.rb",
|
63
|
+
"lib/ironfan/dsl/cluster.rb",
|
64
|
+
"lib/ironfan/dsl/compute.rb",
|
65
|
+
"lib/ironfan/dsl/ec2.rb",
|
66
|
+
"lib/ironfan/dsl/facet.rb",
|
67
|
+
"lib/ironfan/dsl/role.rb",
|
68
|
+
"lib/ironfan/dsl/server.rb",
|
69
|
+
"lib/ironfan/dsl/virtualbox.rb",
|
70
|
+
"lib/ironfan/dsl/volume.rb",
|
71
|
+
"lib/ironfan/headers.rb",
|
72
|
+
"lib/ironfan/provider.rb",
|
73
|
+
"lib/ironfan/provider/chef.rb",
|
74
|
+
"lib/ironfan/provider/chef/client.rb",
|
75
|
+
"lib/ironfan/provider/chef/node.rb",
|
76
|
+
"lib/ironfan/provider/chef/role.rb",
|
77
|
+
"lib/ironfan/provider/ec2.rb",
|
78
|
+
"lib/ironfan/provider/ec2/ebs_volume.rb",
|
79
|
+
"lib/ironfan/provider/ec2/elastic_ip.rb",
|
80
|
+
"lib/ironfan/provider/ec2/key_pair.rb",
|
81
|
+
"lib/ironfan/provider/ec2/machine.rb",
|
82
|
+
"lib/ironfan/provider/ec2/placement_group.rb",
|
83
|
+
"lib/ironfan/provider/ec2/security_group.rb",
|
84
|
+
"lib/ironfan/provider/virtualbox.rb",
|
85
|
+
"lib/ironfan/provider/virtualbox/machine.rb",
|
86
|
+
"lib/ironfan/requirements.rb",
|
74
87
|
"spec/ironfan/cluster_spec.rb",
|
75
88
|
"spec/ironfan/facet_spec.rb",
|
76
89
|
"spec/ironfan/server_slice_spec.rb",
|
@@ -65,30 +65,30 @@ sudo -p 'knife sudo password: ' true
|
|
65
65
|
|
66
66
|
if sudo -p 'knife sudo password: ' service chef-client status ; then
|
67
67
|
|
68
|
-
# running
|
69
|
-
pid_file="<%= config[:pid_file] %>"
|
70
|
-
log_file=<%= config[:log_file] %>
|
68
|
+
# running
|
69
|
+
pid_file="<%= config[:pid_file] %>"
|
70
|
+
log_file=<%= config[:log_file] %>
|
71
71
|
|
72
|
-
declare tail_pid
|
72
|
+
declare tail_pid
|
73
73
|
|
74
|
-
on_exit() {
|
75
|
-
|
76
|
-
|
77
|
-
}
|
74
|
+
on_exit() {
|
75
|
+
rm -f $pipe
|
76
|
+
}
|
78
77
|
|
79
|
-
trap "on_exit" EXIT ERR
|
78
|
+
trap "on_exit" EXIT ERR
|
80
79
|
|
81
|
-
pipe=/tmp/pipe-$$
|
82
|
-
mkfifo $pipe
|
80
|
+
pipe=/tmp/pipe-$$
|
81
|
+
mkfifo $pipe
|
83
82
|
|
84
|
-
tail -Fn0 "$log_file" > $pipe &
|
83
|
+
tail -Fn0 "$log_file" > $pipe &
|
85
84
|
|
86
|
-
tail_pid=$!
|
87
|
-
|
88
|
-
pid="$(sudo -p 'knife sudo password: ' cat $pid_file)"
|
89
|
-
sudo -p 'knife sudo password: ' kill -USR1 "$pid"
|
90
|
-
sed -r "/(ERROR: Sleeping for [0-9]+ seconds before trying again|INFO: Report handlers complete)\$/{q}" $pipe
|
85
|
+
tail_pid=$!
|
91
86
|
|
87
|
+
pid="$(sudo -p 'knife sudo password: ' cat $pid_file)"
|
88
|
+
sudo -p 'knife sudo password: ' kill -USR1 "$pid"
|
89
|
+
GOOD_RESULT='INFO: Report handlers complete\$'
|
90
|
+
BAD_RESULT='ERROR: Sleeping for [0-9]+ seconds before trying again\$'
|
91
|
+
sed -r -e "/$GOOD_RESULT/{q 0}" -e"/$BAD_RESULT/{q 1}" $pipe
|
92
92
|
else
|
93
93
|
echo -e "****\n\nchef-client daemon not running, invoking chef-client directly\n\n****\n"
|
94
94
|
sudo -p 'knife sudo password: ' chef-client
|
@@ -46,26 +46,32 @@ class Chef
|
|
46
46
|
# Execute every last mf'ing one of em
|
47
47
|
def perform_execution(target)
|
48
48
|
if config[:cloud]
|
49
|
-
section("Killing Cloud
|
50
|
-
target.
|
49
|
+
section("Killing Cloud Computers")
|
50
|
+
target.kill :providers => :iaas
|
51
51
|
end
|
52
52
|
|
53
53
|
if config[:chef]
|
54
54
|
section("Killing Chef")
|
55
|
-
target.
|
55
|
+
target.kill :providers => :chef
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
def display(target, *args, &block)
|
60
60
|
super
|
61
|
-
|
62
|
-
|
61
|
+
|
62
|
+
permanent = target.select(&:permanent?)
|
63
|
+
ui.info Formatador.display_line("servers with [red]'permanent=true'[reset] ignored: [blue]#{permanent.map(&:name).inspect}[reset]. (To kill, change 'permanent' to false, run knife cluster sync, and re-try)") unless permanent.empty?
|
64
|
+
|
65
|
+
bogus = target.select(&:bogus?)
|
66
|
+
ui.info Formatador.display_line("[red]Bogus servers detected[reset]: [blue]#{bogus.map(&:name).inspect}[reset]") unless bogus.empty?
|
63
67
|
end
|
64
68
|
|
65
69
|
def confirm_execution(target)
|
70
|
+
nodes = target.map(&:node).compact
|
71
|
+
machines = target.map(&:machine).compact
|
66
72
|
delete_message = [
|
67
|
-
(((!config[:chef]) ||
|
68
|
-
(((!config[:cloud]) ||
|
73
|
+
(((!config[:chef]) || nodes.empty?) ? nil : "#{nodes.length} chef nodes"),
|
74
|
+
(((!config[:cloud]) || machines.empty?) ? nil : "#{machines.length} fog servers") ].compact.join(" and ")
|
69
75
|
confirm_or_exit("Are you absolutely certain that you want to delete #{delete_message}? (Type 'Yes' to confirm) ", 'Yes')
|
70
76
|
end
|
71
77
|
|
@@ -30,7 +30,7 @@ class Chef
|
|
30
30
|
Chef::Knife::ClusterBootstrap.load_deps
|
31
31
|
end
|
32
32
|
|
33
|
-
banner "knife cluster launch CLUSTER[-FACET[-INDEXES]] (options) - Creates chef node and chef apiclient, pre-populates chef node, and instantiates in parallel their cloud
|
33
|
+
banner "knife cluster launch CLUSTER[-FACET[-INDEXES]] (options) - Creates chef node and chef apiclient, pre-populates chef node, and instantiates in parallel their cloud computers. With --bootstrap flag, will ssh in to computers as they become ready and launch the bootstrap process"
|
34
34
|
[ :ssh_port, :ssh_user, :ssh_password, :identity_file, :use_sudo,
|
35
35
|
:prerelease, :bootstrap_version, :template_file, :distro,
|
36
36
|
:bootstrap_runs_chef_client, :host_key_verify
|
@@ -67,81 +67,75 @@ class Chef
|
|
67
67
|
display(full_target)
|
68
68
|
target = full_target.select(&:launchable?)
|
69
69
|
|
70
|
-
warn_or_die_on_bogus_servers(full_target) unless full_target.
|
70
|
+
warn_or_die_on_bogus_servers(full_target) unless full_target.select(&:bogus?).empty?
|
71
71
|
|
72
|
-
die("", "#{ui.color("All
|
72
|
+
die("", "#{ui.color("All computers are running -- not launching any.",:blue)}", "", 1) if target.empty?
|
73
73
|
|
74
74
|
# Pre-populate information in chef
|
75
|
-
section("
|
76
|
-
target.
|
77
|
-
target.sync_to_chef
|
78
|
-
|
79
|
-
# Launch servers
|
80
|
-
section("Launching machines", :green)
|
81
|
-
target.create_servers
|
75
|
+
section("Syncing to chef")
|
76
|
+
target.save :providers => :chef
|
82
77
|
|
78
|
+
# Launch computers
|
83
79
|
ui.info("")
|
80
|
+
section("Launching computers", :green)
|
84
81
|
display(target)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
82
|
+
target.launch
|
83
|
+
|
84
|
+
Chef::Log.warn("Need to set up target.parallelize")
|
85
|
+
# TODO:
|
86
|
+
# # As each server finishes, configure it
|
87
|
+
# watcher_threads = target.parallelize do |svr|
|
88
|
+
# perform_after_launch_tasks(svr)
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# progressbar_for_threads(watcher_threads)
|
92
92
|
|
93
93
|
display(target)
|
94
94
|
end
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
rescue Errno::EHOSTUNREACH
|
140
|
-
sleep 2
|
141
|
-
false
|
142
|
-
ensure
|
143
|
-
tcp_socket && tcp_socket.close
|
144
|
-
end
|
96
|
+
# def perform_after_launch_tasks(server)
|
97
|
+
# # Wait for node creation on amazon side
|
98
|
+
# server.fog_server.wait_for{ ready? }
|
99
|
+
#
|
100
|
+
# # Try SSH
|
101
|
+
# unless config[:dry_run]
|
102
|
+
# nil until tcp_test_ssh(server.fog_server.dns_name){ sleep @initial_sleep_delay ||= 10 }
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# # Make sure our list of volumes is accurate
|
106
|
+
# Ironfan.fetch_fog_volumes
|
107
|
+
# server.discover_volumes!
|
108
|
+
#
|
109
|
+
# # Attach volumes, etc
|
110
|
+
# server.sync_to_cloud
|
111
|
+
#
|
112
|
+
# # Run Bootstrap
|
113
|
+
# if config[:bootstrap]
|
114
|
+
# run_bootstrap(server, server.fog_server.dns_name)
|
115
|
+
# end
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# def tcp_test_ssh(hostname)
|
119
|
+
# tcp_socket = TCPSocket.new(hostname, 22)
|
120
|
+
# readable = IO.select([tcp_socket], nil, nil, 5)
|
121
|
+
# if readable
|
122
|
+
# Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
|
123
|
+
# yield
|
124
|
+
# true
|
125
|
+
# else
|
126
|
+
# false
|
127
|
+
# end
|
128
|
+
# rescue Errno::ETIMEDOUT
|
129
|
+
# false
|
130
|
+
# rescue Errno::ECONNREFUSED
|
131
|
+
# sleep 2
|
132
|
+
# false
|
133
|
+
# rescue Errno::EHOSTUNREACH
|
134
|
+
# sleep 2
|
135
|
+
# false
|
136
|
+
# ensure
|
137
|
+
# tcp_socket && tcp_socket.close
|
138
|
+
# end
|
145
139
|
|
146
140
|
def warn_or_die_on_bogus_servers(target)
|
147
141
|
ui.info("")
|
@@ -31,7 +31,7 @@ class Chef
|
|
31
31
|
|
32
32
|
option :cloud,
|
33
33
|
:long => "--[no-]cloud",
|
34
|
-
:description => "Look up
|
34
|
+
:description => "Look up computers on AWS cloud (default is yes, look up computers; use --no-cloud to skip)",
|
35
35
|
:default => true,
|
36
36
|
:boolean => true
|
37
37
|
|
@@ -52,7 +52,7 @@ class Chef
|
|
52
52
|
# Commands to try:
|
53
53
|
# nn = Chef::Node.load('node-name')
|
54
54
|
# cluster_nodes = cluster.servers.map(&:chef_node)
|
55
|
-
#
|
55
|
+
# fog_computers = cluster.servers.map(&:fog_server)
|
56
56
|
#
|
57
57
|
binding.pry
|
58
58
|
end
|
@@ -30,7 +30,7 @@ class Chef
|
|
30
30
|
|
31
31
|
option :cloud,
|
32
32
|
:long => "--[no-]cloud",
|
33
|
-
:description => "Look up
|
33
|
+
:description => "Look up computers on AWS cloud (default is yes, look up computers; use --no-cloud to skip)",
|
34
34
|
:default => true,
|
35
35
|
:boolean => true
|
36
36
|
|
@@ -46,11 +46,8 @@ class Chef
|
|
46
46
|
# Dump entire contents of objects if -VV flag given
|
47
47
|
#
|
48
48
|
if config[:verbosity] >= 2
|
49
|
-
target.each do |
|
50
|
-
Chef::Log.debug( "
|
51
|
-
Chef::Log.debug( "- volumes: #{JSON.pretty_generate(svr.composite_volumes.values.map(&:to_hash))}" )
|
52
|
-
Chef::Log.debug( "- cloud: #{JSON.pretty_generate(svr.cloud.to_hash)}" )
|
53
|
-
Chef::Log.debug( "- fog: #{JSON.pretty_generate(svr.fog_launch_description)}" )
|
49
|
+
target.each do |computer|
|
50
|
+
Chef::Log.debug( "Computer #{computer.name}: #{JSON.pretty_generate(computer.to_wire)}" )
|
54
51
|
end
|
55
52
|
end
|
56
53
|
|
@@ -41,22 +41,16 @@ class Chef
|
|
41
41
|
:description => "The attribute to use for opening the connection - default is fqdn (ec2 users may prefer cloud.public_hostname)"
|
42
42
|
|
43
43
|
def configure_session
|
44
|
-
target = get_slice(@name_args[0]).select(&:
|
44
|
+
target = get_slice(@name_args[0]).select(&:running?)
|
45
45
|
|
46
46
|
display(target) if config[:verbose] || config[:display_target]
|
47
47
|
|
48
48
|
config[:attribute] ||= Chef::Config[:knife][:ssh_address_attribute] || "fqdn"
|
49
49
|
config[:ssh_user] ||= Chef::Config[:knife][:ssh_user]
|
50
|
-
config[:identity_file] ||= target.ssh_identity_file
|
50
|
+
# config[:identity_file] ||= target.ssh_identity_file
|
51
51
|
|
52
|
-
|
53
|
-
addresses = target.
|
54
|
-
address = svr.public_hostname
|
55
|
-
if address.blank? && (svr.chef_node)
|
56
|
-
address = format_for_display( svr.chef_node )[config[:attribute]]
|
57
|
-
end
|
58
|
-
address
|
59
|
-
end.compact
|
52
|
+
# @action_nodes = target.chef_nodes
|
53
|
+
addresses = target.map {|c| c.machine.public_hostname }.compact
|
60
54
|
|
61
55
|
(ui.fatal("No nodes returned from search!"); exit 10) if addresses.nil? || addresses.length == 0
|
62
56
|
|
@@ -122,8 +116,8 @@ class Chef
|
|
122
116
|
configure_session
|
123
117
|
|
124
118
|
case @name_args[1]
|
119
|
+
when "screen",nil then screen
|
125
120
|
when "interactive" then interactive
|
126
|
-
when "screen" then screen
|
127
121
|
when "tmux" then tmux
|
128
122
|
when "macterm" then macterm
|
129
123
|
when "cssh" then cssh
|
@@ -24,14 +24,12 @@ class Chef
|
|
24
24
|
import_banner_and_options(Ironfan::Script)
|
25
25
|
|
26
26
|
def relevant?(server)
|
27
|
-
server.
|
27
|
+
server.stopped?
|
28
28
|
end
|
29
29
|
|
30
30
|
def perform_execution(target)
|
31
|
-
section("Starting
|
31
|
+
section("Starting computers")
|
32
32
|
super(target)
|
33
|
-
section("Announcing Chef nodes as started")
|
34
|
-
target.send(:delegate_to_servers, :announce_as_started)
|
35
33
|
end
|
36
34
|
|
37
35
|
end
|
@@ -28,10 +28,8 @@ class Chef
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def perform_execution(target)
|
31
|
-
section("Stopping
|
31
|
+
section("Stopping computers")
|
32
32
|
super(target)
|
33
|
-
section("Announcing Chef nodes as stopped")
|
34
|
-
target.send(:delegate_to_servers, :announce_as_stopped)
|
35
33
|
end
|
36
34
|
|
37
35
|
def confirm_execution(target)
|
@@ -21,7 +21,7 @@ require File.expand_path('ironfan_script', File.dirname(File.realdirpath(__FILE_
|
|
21
21
|
class Chef
|
22
22
|
class Knife
|
23
23
|
class ClusterSync < Ironfan::Script
|
24
|
-
import_banner_and_options(Ironfan::Script, :description => "Update chef server and cloud
|
24
|
+
import_banner_and_options(Ironfan::Script, :description => "Update chef server and cloud computers with current cluster definition")
|
25
25
|
|
26
26
|
option :cloud,
|
27
27
|
:long => "--[no-]cloud",
|
@@ -40,38 +40,30 @@ class Chef
|
|
40
40
|
:boolean => true
|
41
41
|
|
42
42
|
|
43
|
-
def relevant?(
|
43
|
+
def relevant?(computer)
|
44
44
|
if config[:sync_all]
|
45
|
-
not
|
45
|
+
not computer.bogus?
|
46
46
|
else
|
47
|
-
|
47
|
+
computer.created? or computer.node?
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
def perform_execution(target)
|
52
52
|
if config[:chef]
|
53
|
-
|
53
|
+
if config[:dry_run]
|
54
|
+
ui.info "(can't do a dry-run when syncing to chef -- skipping)"
|
55
|
+
else
|
56
|
+
ui.info "Syncing to Chef:"
|
57
|
+
target.save :providers => :chef
|
58
|
+
end
|
54
59
|
else Chef::Log.debug("Skipping sync to chef") ; end
|
55
60
|
|
56
|
-
if config[:cloud] && target.any?(&:
|
57
|
-
|
61
|
+
if config[:cloud] && target.any?(&:machine?)
|
62
|
+
ui.info "Syncing to cloud:"
|
63
|
+
target.save :providers => :iaas
|
58
64
|
else Chef::Log.debug("Skipping sync to cloud") ; end
|
59
65
|
end
|
60
66
|
|
61
|
-
def sync_to_chef(target)
|
62
|
-
if config[:dry_run]
|
63
|
-
ui.info "(can't do a dry-run when syncing to chef -- skipping)"
|
64
|
-
return
|
65
|
-
end
|
66
|
-
ui.info "Syncing to Chef:"
|
67
|
-
target.sync_to_chef
|
68
|
-
end
|
69
|
-
|
70
|
-
def sync_to_cloud(target)
|
71
|
-
ui.info "Syncing to cloud:"
|
72
|
-
target.sync_to_cloud
|
73
|
-
end
|
74
|
-
|
75
67
|
end
|
76
68
|
end
|
77
69
|
end
|
@@ -2,6 +2,7 @@ require 'chef/knife'
|
|
2
2
|
|
3
3
|
module Ironfan
|
4
4
|
module KnifeCommon
|
5
|
+
attr_accessor :broker
|
5
6
|
|
6
7
|
def self.load_deps
|
7
8
|
require 'formatador'
|
@@ -17,6 +18,7 @@ module Ironfan
|
|
17
18
|
Ironfan.ui = self.ui
|
18
19
|
self.config[:cloud] = Chef::Config[:cloud] if Chef::Config.has_key?(:cloud)
|
19
20
|
Ironfan.chef_config = self.config
|
21
|
+
self.broker = Ironfan.broker
|
20
22
|
end
|
21
23
|
|
22
24
|
#
|
@@ -37,9 +39,8 @@ module Ironfan
|
|
37
39
|
cluster_name, facet_name, slice_indexes = slice_string.split(/[\s\-]/, 3)
|
38
40
|
ui.info("Inventorying servers in #{predicate_str(cluster_name, facet_name, slice_indexes)}")
|
39
41
|
cluster = Ironfan.load_cluster(cluster_name)
|
40
|
-
|
41
|
-
|
42
|
-
cluster.slice(facet_name, slice_indexes)
|
42
|
+
computers = broker.discover! cluster
|
43
|
+
computers.slice(facet_name, slice_indexes)
|
43
44
|
end
|
44
45
|
|
45
46
|
def predicate_str(cluster_name, facet_name, slice_indexes)
|
@@ -67,18 +68,19 @@ module Ironfan
|
|
67
68
|
#
|
68
69
|
def get_relevant_slice( *predicate )
|
69
70
|
full_target = get_slice( *predicate )
|
70
|
-
display(full_target) do |
|
71
|
-
rel = relevant?(
|
71
|
+
display(full_target) do |m|
|
72
|
+
rel = relevant?(m)
|
72
73
|
{ :relevant? => (rel ? "[blue]#{rel}[reset]" : '-' ) }
|
73
74
|
end
|
74
|
-
full_target.select{|
|
75
|
+
full_target.select{|m| relevant?(m) }
|
75
76
|
end
|
76
77
|
|
77
|
-
# passes target to
|
78
|
+
# passes target to Broker::Conductor#display, will show headings in server slice
|
78
79
|
# tables based on the --verbose flag
|
79
80
|
def display(target, display_style=nil, &block)
|
80
81
|
display_style ||= (config[:verbosity] == 0 ? :default : :expanded)
|
81
|
-
|
82
|
+
# target.display(ui, display_style, &block)
|
83
|
+
broker.display(target,display_style)
|
82
84
|
end
|
83
85
|
|
84
86
|
#
|
@@ -133,7 +135,7 @@ module Ironfan
|
|
133
135
|
def run_bootstrap(node, hostname)
|
134
136
|
bs = bootstrapper(node, hostname)
|
135
137
|
if config[:skip].to_s == 'true'
|
136
|
-
ui.info "Skipping:
|
138
|
+
ui.info "Skipping: bootstrap #{hostname} with #{JSON.pretty_generate(bs.config)}"
|
137
139
|
return
|
138
140
|
end
|
139
141
|
begin
|
@@ -38,12 +38,13 @@ module Ironfan
|
|
38
38
|
|
39
39
|
def run
|
40
40
|
load_ironfan
|
41
|
+
|
41
42
|
die(banner) if @name_args.empty?
|
42
43
|
configure_dry_run
|
43
44
|
|
44
45
|
target = get_relevant_slice(* @name_args)
|
45
46
|
|
46
|
-
die("No
|
47
|
+
die("No computers to #{sub_command}, exiting", 1) if target.empty?
|
47
48
|
|
48
49
|
ui.info(["\n",
|
49
50
|
ui.color("Running #{sub_command}", :cyan),
|