Permalink
Browse files

Merge pull request #2 from schade/feature/196_elastic_ips

Feature/196 elastic ips
  • Loading branch information...
2 parents bfe0b9f + 94287ef commit 13e68a6a939f62da6b62b4772807732d66e537ad Jerry Jackson committed Dec 10, 2012
View
@@ -1,3 +1,8 @@
+# v4.5.2:
+* 'knife cluster launch --bootstrap' should ensure that Chef::Config[:environment] is set, just as 'knife cluster bootstrap' does
+* Cleaning up knife commands to skip bogus servers (fixes #213)
+* EXPERIMENTAL: Adding (cross-platform) ironfaned chef omnibus bootstrap
+
# v4.5.1:
* Clean up on 12.04 template - do dist-upgrade, include omnibus bin in $PATH, nicer first-boot.json
* Removing superfluous raise on duplicate machines during load
View
@@ -1 +1 @@
-4.5.1
+4.5.2
View
@@ -5,11 +5,11 @@
Gem::Specification.new do |s|
s.name = "ironfan"
- s.version = "4.5.1"
+ s.version = "4.5.2"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Infochimps"]
- s.date = "2012-11-14"
+ s.date = "2012-11-27"
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."
s.email = "coders@infochimps.com"
s.extra_rdoc_files = [
@@ -38,6 +38,7 @@ Gem::Specification.new do |s|
"config/ubuntu12.04-ironfan.erb",
"ironfan.gemspec",
"lib/chef/knife/bootstrap/centos6.2-ironfan.erb",
+ "lib/chef/knife/bootstrap/chef-full-ironfan.erb",
"lib/chef/knife/bootstrap/ubuntu10.04-ironfan.erb",
"lib/chef/knife/bootstrap/ubuntu12.04-ironfan.erb",
"lib/chef/knife/cluster_bootstrap.rb",
@@ -120,14 +121,14 @@ Gem::Specification.new do |s|
"notes/walkthrough-hadoop.md",
"notes/walkthrough-web.md",
"spec/chef/cluster_bootstrap_spec.rb",
+ "spec/chef/cluster_launch_spec.rb",
"spec/fixtures/ec2/elb/snakeoil.crt",
"spec/fixtures/ec2/elb/snakeoil.key",
"spec/fixtures/gunbai.rb",
"spec/fixtures/gunbai_slice.json",
"spec/integration/minimal-chef-repo/chefignore",
"spec/integration/minimal-chef-repo/environments/_default.json",
"spec/integration/minimal-chef-repo/knife/credentials/knife-org.rb",
- "spec/integration/minimal-chef-repo/knife/credentials/knife-user-ironfantester.rb",
"spec/integration/minimal-chef-repo/knife/knife.rb",
"spec/integration/minimal-chef-repo/roles/systemwide.rb",
"spec/integration/spec/elb_build_spec.rb",
@@ -148,7 +149,7 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]
s.rubygems_version = "1.8.24"
s.summary = "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."
- s.test_files = ["spec/spec_helper/dummy_chef.rb", "spec/integration/spec_helper/launch_cluster.rb", "spec/integration/minimal-chef-repo/roles/systemwide.rb", "spec/integration/minimal-chef-repo/environments/_default.json", "spec/integration/minimal-chef-repo/chefignore", "spec/integration/minimal-chef-repo/knife/knife.rb", "spec/integration/minimal-chef-repo/knife/credentials/knife-user-ironfantester.rb", "spec/integration/minimal-chef-repo/knife/credentials/knife-org.rb", "spec/integration/spec/simple_cluster_spec.rb", "spec/integration/spec/elb_build_spec.rb", "spec/integration/spec_helper.rb", "spec/ironfan/cluster_spec.rb", "spec/ironfan/ec2/cloud_provider_spec.rb", "spec/ironfan/ec2/elb_spec.rb", "spec/ironfan/ec2/security_group_spec.rb", "spec/chef/cluster_bootstrap_spec.rb", "spec/fixtures/gunbai_slice.json", "spec/fixtures/ec2/elb/snakeoil.key", "spec/fixtures/ec2/elb/snakeoil.crt", "spec/fixtures/gunbai.rb", "spec/spec_helper.rb", "spec/test_config.rb"]
+ s.test_files = ["spec/spec_helper/dummy_chef.rb", "spec/integration/spec_helper/launch_cluster.rb", "spec/integration/minimal-chef-repo/roles/systemwide.rb", "spec/integration/minimal-chef-repo/environments/_default.json", "spec/integration/minimal-chef-repo/chefignore", "spec/integration/minimal-chef-repo/knife/knife.rb", "spec/integration/minimal-chef-repo/knife/credentials/knife-org.rb", "spec/integration/spec/simple_cluster_spec.rb", "spec/integration/spec/elb_build_spec.rb", "spec/integration/spec_helper.rb", "spec/ironfan/cluster_spec.rb", "spec/ironfan/ec2/cloud_provider_spec.rb", "spec/ironfan/ec2/elb_spec.rb", "spec/ironfan/ec2/security_group_spec.rb", "spec/chef/cluster_launch_spec.rb", "spec/chef/cluster_bootstrap_spec.rb", "spec/fixtures/gunbai_slice.json", "spec/fixtures/ec2/elb/snakeoil.key", "spec/fixtures/ec2/elb/snakeoil.crt", "spec/fixtures/gunbai.rb", "spec/spec_helper.rb", "spec/test_config.rb"]
if s.respond_to? :specification_version then
s.specification_version = 3
@@ -0,0 +1,97 @@
+bash -c '
+
+##
+# EXPERIMENTAL
+##
+# This code was submitted as an alternative to the per-distribution scripts, just after a new bootstrap
+# (Ubuntu 12.04) was put into production at Infochimps; therefore, we have had no time to validate it
+# internally. Please exercise caution in applying it.
+#
+# Submitter: Ryan Schlesinger (https://github.com/ryansch)
+# Source: https://github.com/infochimps-labs/ironfan/pull/212
+#
+
+<%= "export http_proxy=\"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] -%>
+
+exists() {
+ if command -v $1 &>/dev/null
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+install_sh="http://opscode.com/chef/install.sh"
+version_string="-v <%= chef_version %>"
+
+if ! exists /usr/bin/chef-client; then
+ if exists wget; then
+ bash <(wget <%= "--proxy=on " if knife_config[:bootstrap_proxy] %> ${install_sh} -O -) ${version_string}
+ else
+ if exists curl; then
+ bash <(curl -L <%= "--proxy=on " if knife_config[:bootstrap_proxy] %> ${install_sh}) ${version_string}
+ fi
+ fi
+fi
+
+mkdir -p /etc/chef
+
+<%- if @config[:client_key] %>
+(
+cat <<'EOP'
+<%= @config[:client_key] %>
+EOP
+) > /tmp/client.pem
+awk NF /tmp/client.pem > /etc/chef/client.pem
+rm /tmp/client.pem
+chmod 0600 /etc/chef/client.pem
+<%- else %>
+(
+cat <<'EOP'
+<%= validation_key %>
+EOP
+) > /tmp/validation.pem
+awk NF /tmp/validation.pem > /etc/chef/validation.pem
+rm /tmp/validation.pem
+chmod 0600 /etc/chef/validation.pem
+<% end -%>
+
+<% if @chef_config[:encrypted_data_bag_secret] -%>
+(
+cat <<'EOP'
+<%= encrypted_data_bag_secret %>
+EOP
+) > /tmp/encrypted_data_bag_secret
+awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret
+rm /tmp/encrypted_data_bag_secret
+chmod 0600 /etc/chef/encrypted_data_bag_secret
+<% end -%>
+
+<%# Generate Ohai Hints -%>
+<% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
+mkdir -p /etc/chef/ohai/hints
+
+<% @chef_config[:knife][:hints].each do |name, hash| -%>
+(
+cat <<'EOP'
+<%= hash.to_json %>
+EOP
+) > /etc/chef/ohai/hints/<%= name %>.json
+<% end -%>
+<% end -%>
+
+(
+cat <<'EOP'
+<%= config_content %>
+<%= @config[:computer].chef_client_script_content %>
+EOP
+) > /etc/chef/client.rb
+
+(
+cat <<'EOP'
+<%= { "run_list" => @run_list, "cluster_name" => @config[:server].cluster_name, "facet_name" => @config[:server].facet_name, "facet_index" => @config[:server].index }.to_json %>
+EOP
+) > /etc/chef/first-boot.json
+
+<%= start_chef %>'
@@ -59,7 +59,7 @@ class ClusterBootstrap < Ironfan::Script
end
def perform_execution(target)
- reconcile_chef_config(target)
+ ensure_common_environment(target)
# Execute across all servers in parallel
Ironfan.parallel(target.values) {|computer| run_bootstrap(computer)}
# threads = target.servers.map{ |server| Thread.new(server) { |svr| run_bootstrap(svr, svr.public_hostname) } }
@@ -70,18 +70,6 @@ def confirm_execution(target)
confirm_or_exit("Are you absolutely certain that you want to perform this action? (Type 'Yes' to confirm) ", 'Yes')
end
- protected
-
- def reconcile_chef_config(target)
- environments = target.environments
- if environments.length > 1
- ui.error "You cannot bootstrap machines in multiple chef environments: got #{environments.inspect} from #{target.map(&:name)}"
- ui.error "Re-run this command on each subgroup of machines that share an environment"
- raise StandardError, "Cannot bootstrap multiple chef environments"
- end
- Chef::Config[:environment] = environments.first
- end
-
end
end
end
@@ -71,6 +71,13 @@ def run
die("", "#{ui.color("All computers are running -- not launching any.",:blue)}", "", 1) if target.empty?
+ # If a bootstrap was requested, ensure that we will be able to perform the
+ # bootstrap *before* trying to launch all of the servers in target. This
+ # will save the user a lot of time if they've made a configuration mistake
+ if config[:bootstrap]
+ ensure_common_environment(target)
+ end
+
# Pre-populate information in chef
section("Syncing to chef")
target.save :providers => :chef
@@ -80,7 +87,6 @@ def run
section("Launching computers", :green)
display(target)
launched = target.launch
-
# As each server finishes, configure it
Ironfan.parallel(launched) do |computer|
if (computer.is_a?(Exception)) then ui.warn "Error launching #{computer.inspect}; skipping after-launch tasks."; next; end
@@ -100,7 +106,7 @@ def perform_after_launch_tasks(computer)
Ironfan.step(computer.name, 'waiting for ready', :white)
# Wait for machine creation on amazon side
computer.machine.wait_for{ ready? }
-
+
# Try SSH
unless config[:dry_run]
Ironfan.step(computer.name, 'trying ssh', :white)
@@ -109,7 +115,7 @@ def perform_after_launch_tasks(computer)
Ironfan.step(computer.name, 'final provisioning', :white)
computer.save
-
+
# Run Bootstrap
if config[:bootstrap]
Chef::Log.warn "UNTESTED --bootstrap"
@@ -50,6 +50,7 @@ def configure_session
# config[:identity_file] ||= target.ssh_identity_file
# @action_nodes = target.chef_nodes
+ target = target.select {|t| not t.bogus? }
addresses = target.map {|c| c.machine.public_hostname }.compact
(ui.fatal("No nodes returned from search!"); exit 10) if addresses.nil? || addresses.length == 0
@@ -41,11 +41,9 @@ class ClusterSync < Ironfan::Script
def relevant?(computer)
- if config[:sync_all]
- not computer.bogus?
- else
- computer.created? or computer.node?
- end
+ return false if computer.bogus?
+ return true if config[:sync_all]
+ computer.created? or computer.node?
end
def perform_execution(target)
@@ -237,5 +237,18 @@ def self.included(base)
extend ClassMethods
end
end
+
+ protected
+
+ def ensure_common_environment(target)
+ environments = target.environments
+ if environments.length > 1
+ ui.error "You cannot bootstrap machines in multiple chef environments: got #{environments.inspect} from #{target.map(&:name)}"
+ ui.error "Re-run this command on each subgroup of machines that share an environment"
+ raise StandardError, "Cannot bootstrap multiple chef environments"
+ end
+ Chef::Config[:environment] = environments.first
+ end
+
end
end
@@ -301,7 +301,7 @@ def validate
def aggregate
computers = self
provider_keys = values.map {|c| c.chosen_providers({ :providers => :iaas})}.flatten.uniq
- providers = provider_keys.map { |pk| values.map { |c| c.providers[pk] } }.flatten.uniq
+ providers = provider_keys.map { |pk| values.map { |c| c.providers[pk] } }.flatten.compact.uniq
providers.each { |p| p.aggregate! computers }
end
View
@@ -14,7 +14,7 @@ class Ec2 < Cloud
magic :bootstrap_distro, String, :default => ->{ image_info[:bootstrap_distro] }
magic :chef_client_script, String
magic :default_availability_zone, String, :default => ->{ availability_zones.first }
- magic :elastic_ip, String
+ magic :domain, String, :default => 'standard'
collection :elastic_load_balancers, Ironfan::Dsl::Ec2::ElasticLoadBalancer, :key_method => :name
magic :flavor, String, :default => 't1.micro'
collection :iam_server_certificates, Ironfan::Dsl::Ec2::IamServerCertificate, :key_method => :name
@@ -26,7 +26,7 @@ class Ec2 < Cloud
magic :permanent, :boolean, :default => false
magic :placement_group, String
magic :provider, Whatever, :default => Ironfan::Provider::Ec2
- magic :public_ip, String
+ magic :elastic_ip, String
magic :region, String, :default => ->{ default_region }
collection :security_groups, Ironfan::Dsl::Ec2::SecurityGroup, :key_method => :name
magic :ssh_user, String, :default => ->{ image_info[:ssh_user] }
@@ -62,8 +62,7 @@ def to_display(style,values={})
values["AZ"] = default_availability_zone
return values if style == :default
- # values["Elastic IP"] = public_ip if public_ip
- values["Elastic IP"] = elastic_ip if elastic_ip
+ values["Public IP"] = elastic_ip if elastic_ip
values
end
@@ -279,8 +278,8 @@ class IamServerCertificate < Ironfan::Dsl
# 32-or-64: m1.small, m1.medium, t1.micro, c1.medium
't1.micro' => { :price => 0.02, :bits => 64, :ram => 686, :cores => 1, :core_size => 0.25, :inst_disks => 0, :inst_disk_size => 0, :ephemeral_volumes => 0 },
'm1.small' => { :price => 0.08, :bits => 64, :ram => 1740, :cores => 1, :core_size => 1, :inst_disks => 1, :inst_disk_size => 160, :ephemeral_volumes => 1 },
- 'm1.medium' => { :price => 0.165, :bits => 32, :ram => 3840, :cores => 2, :core_size => 1, :inst_disks => 1, :inst_disk_size => 410, :ephemeral_volumes => 1 },
- 'c1.medium' => { :price => 0.17, :bits => 32, :ram => 1740, :cores => 2, :core_size => 2.5, :inst_disks => 1, :inst_disk_size => 350, :ephemeral_volumes => 1 },
+ 'm1.medium' => { :price => 0.165, :bits => 64, :ram => 3840, :cores => 2, :core_size => 1, :inst_disks => 1, :inst_disk_size => 410, :ephemeral_volumes => 1 },
+ 'c1.medium' => { :price => 0.17, :bits => 64, :ram => 1740, :cores => 2, :core_size => 2.5, :inst_disks => 1, :inst_disk_size => 350, :ephemeral_volumes => 1 },
#
'm1.large' => { :price => 0.32, :bits => 64, :ram => 7680, :cores => 2, :core_size => 2, :inst_disks => 2, :inst_disk_size => 850, :ephemeral_volumes => 2 },
'm2.xlarge' => { :price => 0.45, :bits => 64, :ram => 18124, :cores => 2, :core_size => 3.25, :inst_disks => 1, :inst_disk_size => 420, :ephemeral_volumes => 1 },
@@ -5,7 +5,7 @@ class Ec2 < Ironfan::IaasProvider
self.handle = :ec2
def self.resources
- [ Machine, EbsVolume, Keypair, SecurityGroup, IamServerCertificate, ElasticLoadBalancer ]
+ [ Machine, ElasticIp, EbsVolume, Keypair, SecurityGroup, IamServerCertificate, ElasticLoadBalancer ]
end
#
@@ -15,13 +15,6 @@ def self.connection
@@connection ||= Fog::Compute.new(self.aws_credentials.merge({ :provider => 'AWS' }))
end
- def self.eip
- c ||= Fog::Compute.new(self.aws_credentials.merge({ :provider => 'AWS' }))
- address = c.addresses.create
- address.server = server
- server.reload
- end
-
def self.elb
@@elb ||= Fog::AWS::ELB.new(self.aws_credentials)
end
Oops, something went wrong.

0 comments on commit 13e68a6

Please sign in to comment.