rubber 2.4.2 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22e517ff32f6b1a5ebb0bbc229d619493e377d1a
4
- data.tar.gz: 117569a34d40c27d17d0f62c587109b4aa32c1e9
3
+ metadata.gz: eea69e220cb373705e078eaa52e02f5e90a170d6
4
+ data.tar.gz: ff4b8c6ed5e32ce6bbbcc40987e11cf675d83af8
5
5
  SHA512:
6
- metadata.gz: 06b55aeb4476092dc3d9d6fab6d7bf8819228a086afed91c2a014970d196ce6970761961d74c3274192d0e0f80df42003f7f4d80eeccedf3d78b2f3cac50fd92
7
- data.tar.gz: e769eecb972f75a414f9bf3b04d670d335fa0822bd8ec2c3eae7578fff8ca5258a0940a3f5d2a46356aae3a6a82a2abb2863d5d5aa353cfa2a4b8c8aa8c641d4
6
+ metadata.gz: 0402e07cef45eb6e2d109161e7fee64fd1cf81375b4be06a804462855b15828a5236b26aabf8f35863a7bfd69f828f40067c134f902e476327a0c3f36213de3a
7
+ data.tar.gz: 57b6878e9a38472c947019b9d8283a773b59bf082ea3529ffa80dfb13fd5cda5a2a3b85dc83fb3c35dc71af93bd81f321099be9431f84085cc11babd835083af
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ 2.5.0 (06/03/2013)
2
+ -----------------
3
+
4
+ New Features:
5
+ ============
6
+
7
+ [core] Added support for using Rubber as a Vagrant provisioner. Now you can run Rubber easily against local VMs.
8
+
9
+
1
10
  2.4.2 (06/01/2013)
2
11
  ------------------
3
12
 
@@ -76,6 +76,11 @@ require 'rubber/util'
76
76
  require 'rubber/cloud'
77
77
  require 'rubber/dns'
78
78
 
79
+ if defined?(::Vagrant)
80
+ require 'rubber/vagrant/plugin'
81
+ end
82
+
83
+
79
84
  if defined?(Rails::Railtie)
80
85
  module Rubber
81
86
  require 'rubber/railtie'
@@ -64,6 +64,10 @@ module Rubber
64
64
  'running'
65
65
  end
66
66
 
67
+ def stopped_state
68
+ 'stopped'
69
+ end
70
+
67
71
  def before_create_instance(instance_alias, role_names)
68
72
  setup_security_groups(instance_alias, role_names)
69
73
  end
@@ -83,7 +87,25 @@ module Rubber
83
87
  Rubber::Tag::update_instance_tags(instance.name)
84
88
  end
85
89
  end
86
-
90
+
91
+ def before_stop_instance(instance)
92
+ capistrano.fatal "Cannot stop spot instances!" if ! instance.spot_instance_request_id.nil?
93
+ capistrano.fatal "Cannot stop instances with instance-store root device!" if (instance.root_device_type != 'ebs')
94
+ end
95
+
96
+ def before_start_instance(instance)
97
+ capistrano.fatal "Cannot start spot instances!" if ! instance.spot_instance_request_id.nil?
98
+ capistrano.fatal "Cannot start instances with instance-store root device!" if (instance.root_device_type != 'ebs')
99
+ end
100
+
101
+ def after_start_instance(instance)
102
+ # Re-starting an instance will almost certainly give it a new set of IPs and DNS entries, so refresh the values.
103
+ capistrano.rubber.refresh_instance(instance.name)
104
+
105
+ # Static IPs, DNS, etc. need to be set up for the started instance.
106
+ capistrano.rubber.post_refresh
107
+ end
108
+
87
109
  def create_image(image_name)
88
110
 
89
111
  # validate all needed config set
@@ -26,6 +26,22 @@ module Rubber
26
26
  setup_security_groups(instance.name, instance.role_names)
27
27
  end
28
28
 
29
+ def before_stop_instance(instance)
30
+ # No-op by default.
31
+ end
32
+
33
+ def after_stop_instance(instance)
34
+ # No-op by default.
35
+ end
36
+
37
+ def before_start_instance(instance)
38
+ # No-op by default.
39
+ end
40
+
41
+ def after_start_instance(instance)
42
+ # No-op by default.
43
+ end
44
+
29
45
  def isolate_prefix
30
46
  "#{env.app_name}_#{Rubber.env}_"
31
47
  end
@@ -48,13 +48,13 @@ module Rubber
48
48
  response = @compute_provider.servers.get(instance_id).reboot()
49
49
  end
50
50
 
51
- def stop_instance(instance_id, force=false)
51
+ def stop_instance(instance, force=false)
52
52
  # Don't force the stop process. I.e., allow the instance to flush its file system operations.
53
- response = @compute_provider.servers.get(instance_id).stop(force)
53
+ response = @compute_provider.servers.get(instance.instance_id).stop(force)
54
54
  end
55
55
 
56
- def start_instance(instance_id)
57
- response = @compute_provider.servers.get(instance_id).start()
56
+ def start_instance(instance)
57
+ response = @compute_provider.servers.get(instance.instance_id).start()
58
58
  end
59
59
 
60
60
  def create_static_ip
@@ -45,7 +45,7 @@ module Rubber
45
45
  # Since there's no API to query for instance details, the best we can do is use what we have in memory from
46
46
  # the :create_instance operation or ask the user for the details again.
47
47
  unless Generic.instances
48
- create_instance(instance_id, nil, nil, nil, nil)
48
+ create_instance(instance_id, nil, nil, nil, nil, nil)
49
49
  end
50
50
 
51
51
  Generic.instances
@@ -0,0 +1,57 @@
1
+ require 'rubber/cloud/generic'
2
+
3
+ module Rubber
4
+ module Cloud
5
+ class Vagrant < Generic
6
+
7
+ def active_state
8
+ 'running'
9
+ end
10
+
11
+ def stopped_state
12
+ 'saved'
13
+ end
14
+
15
+ def before_create_instance(instance_alias, role_names)
16
+ unless ENV.has_key?('RUN_FROM_VAGRANT')
17
+ capistrano.fatal "Since you are using the 'vagrant' provider, you must create instances by running `vagrant up #{instance_alias}`."
18
+ end
19
+ end
20
+
21
+ def describe_instances(instance_id=nil)
22
+ output = `vagrant status #{instance_id}`
23
+
24
+ output =~ /#{instance_id}\s+(\w+)/m
25
+ state = $1
26
+
27
+ if Generic.instances
28
+ Generic.instances.each do |instance|
29
+ if instance[:id] == instance_id
30
+ instance[:state] = state
31
+ end
32
+ end
33
+
34
+ Generic.instances
35
+ else
36
+ instance = {}
37
+ instance[:id] = instance_id
38
+ instance[:state] = state
39
+
40
+ [instance]
41
+ end
42
+ end
43
+
44
+ def destroy_instance(instance_id)
45
+ system("vagrant destroy #{instance_id} --force")
46
+ end
47
+
48
+ def stop_instance(instance, force=false)
49
+ system("vagrant suspend #{instance.instance_id}")
50
+ end
51
+
52
+ def start_instance(instance)
53
+ system("vagrant resume #{instance.instance_id}")
54
+ end
55
+ end
56
+ end
57
+ end
@@ -65,7 +65,8 @@ namespace :rubber do
65
65
  # NOTE: for some reason Capistrano requires you to have both the public and
66
66
  # the private key in the same folder, the public key should have the
67
67
  # extension ".pub".
68
- ssh_options[:keys] = [cloud.env.key_file].flatten
68
+
69
+ ssh_options[:keys] = [ENV['RUBBER_SSH_KEY'] || cloud.env.key_file].flatten.compact
69
70
  ssh_options[:timeout] = fetch(:ssh_timeout, 5)
70
71
  end
71
72
 
@@ -220,7 +220,7 @@ namespace :rubber do
220
220
  value = Capistrano::CLI.ui.ask("You do not have a primary db role, should #{instance_alias} be it [y/n]?: ")
221
221
  roles << "db:primary=true" if value =~ /^y/
222
222
  end
223
-
223
+
224
224
  ir.concat roles.collect {|r| Rubber::Configuration::RoleItem.parse(r) }
225
225
 
226
226
  # Add in roles that the given set of roles depends on
@@ -255,7 +255,7 @@ namespace :rubber do
255
255
  post_refresh
256
256
  end
257
257
 
258
- set :mutex, Mutex.new
258
+ set :monitor, Monitor.new
259
259
 
260
260
  # Creates a new ec2 instance with the given alias and roles
261
261
  # Configures aliases (/etc/hosts) on local and remote machines
@@ -263,7 +263,7 @@ namespace :rubber do
263
263
  role_names = instance_roles.collect{|x| x.name}
264
264
  env = rubber_cfg.environment.bind(role_names, instance_alias)
265
265
 
266
- mutex.synchronize do
266
+ monitor.synchronize do
267
267
  cloud.before_create_instance(instance_alias, role_names)
268
268
  end
269
269
 
@@ -318,7 +318,7 @@ namespace :rubber do
318
318
  rubber_instances.add(instance_item)
319
319
  rubber_instances.save()
320
320
 
321
- mutex.synchronize do
321
+ monitor.synchronize do
322
322
  cloud.after_create_instance(instance_item)
323
323
  end
324
324
  end
@@ -350,7 +350,7 @@ namespace :rubber do
350
350
 
351
351
  instance = cloud.describe_instances(instance_item.instance_id).first
352
352
 
353
- mutex.synchronize do
353
+ monitor.synchronize do
354
354
  cloud.before_refresh_instance(instance_item)
355
355
  end
356
356
 
@@ -386,7 +386,7 @@ namespace :rubber do
386
386
  end
387
387
  end
388
388
 
389
- mutex.synchronize do
389
+ monitor.synchronize do
390
390
  cloud.after_refresh_instance(instance_item)
391
391
  end
392
392
 
@@ -499,11 +499,15 @@ namespace :rubber do
499
499
  instance_item = rubber_instances[instance_alias]
500
500
 
501
501
  fatal "Instance does not exist: #{instance_alias}" if ! instance_item
502
- fatal "Cannot stop spot instances!" if ! instance_item.spot_instance_request_id.nil?
503
- fatal "Cannot stop instances with instance-store root device!" if (instance_item.root_device_type != 'ebs')
504
502
 
505
503
  instance_item
506
504
  end
505
+
506
+ monitor.synchronize do
507
+ instance_items.each do |instance_item|
508
+ cloud.before_stop_instance(instance_item)
509
+ end
510
+ end
507
511
 
508
512
  # Get user confirmation
509
513
  human_instance_list = instance_items.collect{|instance_item| "#{instance_item.name} (#{instance_item.instance_id})"}.join(', ')
@@ -516,13 +520,13 @@ namespace :rubber do
516
520
  stop_threads << Thread.new do
517
521
  env = rubber_cfg.environment.bind(instance_item.role_names, instance_item.name)
518
522
 
519
- cloud.stop_instance(instance_item.instance_id)
523
+ cloud.stop_instance(instance_item)
520
524
 
521
525
  stopped = false
522
526
  while !stopped
523
527
  sleep 1
524
528
  instance = cloud.describe_instances(instance_item.instance_id).first rescue {}
525
- stopped = (instance[:state] == "stopped")
529
+ stopped = (instance[:state] == cloud.stopped_state)
526
530
  end
527
531
  end
528
532
  end
@@ -536,23 +540,33 @@ namespace :rubber do
536
540
  print "\n"
537
541
 
538
542
  stop_threads.each(&:join)
543
+
544
+ monitor.synchronize do
545
+ instance_items.each do |instance_item|
546
+ cloud.after_stop_instance(instance_item)
547
+ end
548
+ end
539
549
  end
540
550
 
541
551
  # Starts the given ec2 instances. Note that this operation only works for instances that use an EBS volume for the root
542
552
  # device, that are not spot instances, and that are already stopped.
543
553
  def start_instances(aliases)
544
554
  start_threads = []
545
- refresh_threads = []
555
+ describe_threads = []
546
556
 
547
557
  instance_items = aliases.collect do |instance_alias|
548
558
  instance_item = rubber_instances[instance_alias]
549
559
 
550
560
  fatal "Instance does not exist: #{instance_alias}" if ! instance_item
551
- fatal "Cannot start spot instances!" if ! instance_item.spot_instance_request_id.nil?
552
- fatal "Cannot start instances with instance-store root device!" if (instance_item.root_device_type != 'ebs')
553
561
 
554
562
  instance_item
555
563
  end
564
+
565
+ monitor.synchronize do
566
+ instance_items.each do |instance_item|
567
+ cloud.before_start_instance(instance_item)
568
+ end
569
+ end
556
570
 
557
571
  # Get user confirmation
558
572
  human_instance_list = instance_items.collect{|instance_item| "#{instance_item.name} (#{instance_item.instance_id})"}.join(', ')
@@ -565,12 +579,14 @@ namespace :rubber do
565
579
  start_threads << Thread.new do
566
580
  env = rubber_cfg.environment.bind(instance_item.role_names, instance_item.name)
567
581
 
568
- cloud.start_instance(instance_item.instance_id)
569
-
570
- # Re-starting an instance will almost certainly give it a new set of IPs and DNS entries, so refresh the values.
571
- refresh_threads << Thread.new do
572
- while ! refresh_instance(instance_item.name)
582
+ cloud.start_instance(instance_item)
583
+
584
+ describe_threads << Thread.new do
585
+ started = false
586
+ while ! started
573
587
  sleep 1
588
+ instance = cloud.describe_instances(instance_item.instance_id).first rescue {}
589
+ started = (instance[:state] == cloud.active_state)
574
590
  end
575
591
  end
576
592
  end
@@ -584,10 +600,13 @@ namespace :rubber do
584
600
  end
585
601
 
586
602
  start_threads.each(&:join)
587
- refresh_threads.each(&:join)
588
-
589
- # Static IPs, DNS, etc. need to be set up for the started instances
590
- post_refresh
603
+ describe_threads.each(&:join)
604
+
605
+ monitor.synchronize do
606
+ instance_items.each do |instance_item|
607
+ cloud.after_start_instance(instance_item)
608
+ end
609
+ end
591
610
  end
592
611
 
593
612
  # delete from ~/.ssh/known_hosts all lines that begin with ec2- or instance_alias
@@ -9,8 +9,8 @@ namespace :rubber do
9
9
  link_bash
10
10
  set_timezone
11
11
  enable_multiverse
12
- install_core_packages
13
12
  upgrade_packages
13
+ install_core_packages
14
14
  install_packages
15
15
  setup_volumes
16
16
  setup_gem_sources
@@ -26,7 +26,7 @@ namespace :rubber do
26
26
  # We special-case the 'ubuntu' user since Amazon doesn't since the Canonical AMIs on EC2 don't set the password for
27
27
  # this account, making any password prompt potentially confusing.
28
28
  orig_password = fetch(:password)
29
- set(:password, initial_ssh_user == 'ubuntu' ? nil : Capistrano::CLI.password_prompt("Password for #{initial_ssh_user} @ #{ip}: "))
29
+ set(:password, initial_ssh_user == 'ubuntu' || ENV.has_key?('RUN_FROM_VAGRANT') ? nil : Capistrano::CLI.password_prompt("Password for #{initial_ssh_user} @ #{ip}: "))
30
30
 
31
31
  task :_allow_root_ssh, :hosts => "#{initial_ssh_user}@#{ip}" do
32
32
  rsudo "mkdir -p /root/.ssh && cp /home/#{initial_ssh_user}/.ssh/authorized_keys /root/.ssh/"
@@ -0,0 +1,32 @@
1
+ module VagrantPlugins
2
+ module Rubber
3
+ class Config < Vagrant.plugin("2", :config)
4
+ attr_accessor :roles, :rubber_env
5
+
6
+ def initialize
7
+ @roles = UNSET_VALUE
8
+ @rubber_env = UNSET_VALUE
9
+ end
10
+
11
+ def finalize!
12
+ @rubber_env = 'vagrant' if @rubber_env == UNSET_VALUE
13
+
14
+ ::Rubber::initialize(Dir.pwd, @rubber_env)
15
+
16
+ @roles = ::Rubber.config['staging_roles'] if @roles == UNSET_VALUE
17
+ end
18
+
19
+ def validate(machine)
20
+ if @rubber_env.nil?
21
+ return { 'rubber' => ['rubber_env must be set to the Rubber environment to use for this cluster'] }
22
+ end
23
+
24
+ if @roles.nil?
25
+ return { 'rubber' => ['roles must be set to a list of roles to use for this machine'] }
26
+ end
27
+
28
+ {}
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ module VagrantPlugins
2
+ module Rubber
3
+ class Plugin < Vagrant.plugin("2")
4
+ name 'rubber'
5
+ description 'Provides support for provisioning your virtual machines with Rubber.'
6
+
7
+ config(:rubber, :provisioner) do
8
+ require File.expand_path('../config', __FILE__)
9
+ Config
10
+ end
11
+
12
+ provisioner(:rubber) do
13
+ require File.expand_path('../provisioner', __FILE__)
14
+ Provisioner
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,59 @@
1
+ module VagrantPlugins
2
+ module Rubber
3
+ class Provisioner < Vagrant.plugin("2", :provisioner)
4
+ attr_reader :ssh_info, :private_ip
5
+
6
+ def configure(root_config)
7
+ root_config.vm.networks.each do |type, info|
8
+ if type == :private_network
9
+ @private_ip = info[:ip]
10
+ end
11
+ end
12
+
13
+ if @private_ip.nil?
14
+ $stderr.puts "Rubber requires a private network address to be configured in your Vagrantfile."
15
+ exit(-1)
16
+ end
17
+ end
18
+
19
+ def provision
20
+ @ssh_info = machine.ssh_info
21
+
22
+ create
23
+ bootstrap && deploy_migrations
24
+ end
25
+
26
+ private
27
+
28
+ def create
29
+ script = <<-ENDSCRIPT
30
+ unset GEM_HOME;
31
+ unset GEM_PATH;
32
+ PATH=#{ENV['PATH'].split(':')[1..-1].join(':')} RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} ALIAS=#{machine.name} ROLES='#{config.roles}' EXTERNAL_IP=#{private_ip} INTERNAL_IP=#{private_ip} RUBBER_SSH_KEY=#{ssh_info[:private_key_path]} bash -c 'bundle exec cap rubber:create -S initial_ssh_user=#{ssh_info[:username]}'
33
+ ENDSCRIPT
34
+
35
+ system(script)
36
+ end
37
+
38
+ def bootstrap
39
+ script = <<-ENDSCRIPT
40
+ unset GEM_HOME;
41
+ unset GEM_PATH;
42
+ PATH=#{ENV['PATH'].split(':')[1..-1].join(':')} RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{ssh_info[:private_key_path]} FILTER=#{machine.name} bash -c 'bundle exec cap rubber:bootstrap'
43
+ ENDSCRIPT
44
+
45
+ system(script)
46
+ end
47
+
48
+ def deploy_migrations
49
+ script = <<-ENDSCRIPT
50
+ unset GEM_HOME;
51
+ unset GEM_PATH;
52
+ PATH=#{ENV['PATH'].split(':')[1..-1].join(':')} RUN_FROM_VAGRANT=true RUBBER_ENV=#{config.rubber_env} RUBBER_SSH_KEY=#{ssh_info[:private_key_path]} FILTER=#{machine.name} bash -c 'bundle exec cap deploy:migrations'
53
+ ENDSCRIPT
54
+
55
+ system(script)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,3 +1,3 @@
1
1
  module Rubber
2
- VERSION = "2.4.2"
2
+ VERSION = "2.5.0"
3
3
  end
@@ -0,0 +1,7 @@
1
+ cloud_provider: vagrant
2
+
3
+ cloud_providers:
4
+ vagrant:
5
+ # Rubber assumes every cloud provider has configuration. Vagrant really doesn't need anything, but until the core
6
+ # of Rubber handles that, just set a dummy value.
7
+ dummy: true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.2
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Conway
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-01 00:00:00.000000000 Z
12
+ date: 2013-06-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -215,6 +215,7 @@ files:
215
215
  - lib/rubber/cloud/fog.rb
216
216
  - lib/rubber/cloud/fog_storage.rb
217
217
  - lib/rubber/cloud/generic.rb
218
+ - lib/rubber/cloud/vagrant.rb
218
219
  - lib/rubber/commands/config.rb
219
220
  - lib/rubber/commands/cron.rb
220
221
  - lib/rubber/commands/util.rb
@@ -246,6 +247,9 @@ files:
246
247
  - lib/rubber/tag.rb
247
248
  - lib/rubber/thread_safe_proxy.rb
248
249
  - lib/rubber/util.rb
250
+ - lib/rubber/vagrant/config.rb
251
+ - lib/rubber/vagrant/plugin.rb
252
+ - lib/rubber/vagrant/provisioner.rb
249
253
  - lib/rubber/version.rb
250
254
  - rails/init.rb
251
255
  - rubber.gemspec
@@ -273,6 +277,7 @@ files:
273
277
  - templates/base/config/rubber/deploy-util.rb
274
278
  - templates/base/config/rubber/rubber-dns.yml
275
279
  - templates/base/config/rubber/rubber-ruby.yml
280
+ - templates/base/config/rubber/rubber-vagrant-env.yml
276
281
  - templates/base/config/rubber/rubber.yml
277
282
  - templates/base/script/rubber
278
283
  - templates/base/templates.rb