dew 0.1.0
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.
- data/LICENSE +22 -0
- data/README.md +38 -0
- data/Rakefile +26 -0
- data/bin/dew +87 -0
- data/config/cucumber.yaml +4 -0
- data/features/create-ami.feature +16 -0
- data/features/create-environments.feature +46 -0
- data/features/deploy-puge.feature +16 -0
- data/features/step_definitions/aws-steps.rb +101 -0
- data/features/step_definitions/deploy-puge-steps.rb +27 -0
- data/features/support/env.rb +38 -0
- data/features/support/hooks.rb +10 -0
- data/lib/dew.rb +7 -0
- data/lib/dew/aws_resources.yaml +122 -0
- data/lib/dew/base_command.rb +24 -0
- data/lib/dew/cloud.rb +79 -0
- data/lib/dew/commands.rb +6 -0
- data/lib/dew/commands/ami.rb +67 -0
- data/lib/dew/commands/console.rb +17 -0
- data/lib/dew/commands/console/irb_override.rb +24 -0
- data/lib/dew/commands/deploy.rb +114 -0
- data/lib/dew/commands/deploy/templates/apache.conf.erb +28 -0
- data/lib/dew/commands/deploy/templates/known_hosts +2 -0
- data/lib/dew/commands/deploy/templates/rvmrc +2 -0
- data/lib/dew/commands/environments.rb +110 -0
- data/lib/dew/commands/tidy.rb +35 -0
- data/lib/dew/controllers.rb +3 -0
- data/lib/dew/controllers/amis_controller.rb +82 -0
- data/lib/dew/controllers/deploy_controller.rb +10 -0
- data/lib/dew/controllers/environments_controller.rb +48 -0
- data/lib/dew/models.rb +7 -0
- data/lib/dew/models/account.rb +30 -0
- data/lib/dew/models/database.rb +32 -0
- data/lib/dew/models/deploy.rb +2 -0
- data/lib/dew/models/deploy/puge.rb +61 -0
- data/lib/dew/models/deploy/run.rb +19 -0
- data/lib/dew/models/environment.rb +199 -0
- data/lib/dew/models/fog_model.rb +23 -0
- data/lib/dew/models/profile.rb +60 -0
- data/lib/dew/models/server.rb +134 -0
- data/lib/dew/password.rb +7 -0
- data/lib/dew/tasks/spec.rake +14 -0
- data/lib/dew/validations.rb +8 -0
- data/lib/dew/version.rb +3 -0
- data/lib/dew/view.rb +39 -0
- data/lib/tasks/spec.rake +14 -0
- data/spec/dew/cloud_spec.rb +90 -0
- data/spec/dew/controllers/amis_controller_spec.rb +137 -0
- data/spec/dew/controllers/deploy_controller_spec.rb +38 -0
- data/spec/dew/controllers/environments_controller_spec.rb +133 -0
- data/spec/dew/models/account_spec.rb +47 -0
- data/spec/dew/models/database_spec.rb +58 -0
- data/spec/dew/models/deploy/puge_spec.rb +72 -0
- data/spec/dew/models/deploy/run_spec.rb +38 -0
- data/spec/dew/models/environment_spec.rb +374 -0
- data/spec/dew/models/fog_model_spec.rb +24 -0
- data/spec/dew/models/profile_spec.rb +85 -0
- data/spec/dew/models/server_spec.rb +190 -0
- data/spec/dew/password_spec.rb +11 -0
- data/spec/dew/spec_helper.rb +22 -0
- data/spec/dew/view_spec.rb +38 -0
- metadata +284 -0
    
        data/lib/dew.rb
    ADDED
    
    
| @@ -0,0 +1,122 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            regions:
         | 
| 3 | 
            +
              us-east-1: US East (Virginia)
         | 
| 4 | 
            +
              us-west-1: US West (North California)
         | 
| 5 | 
            +
              eu-west-1: EU West (Ireland)
         | 
| 6 | 
            +
              ap-southeast-1: Asia Pacific (Singapore)
         | 
| 7 | 
            +
              ap-northeast-1: Asia Pacific (Tokyo)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            instance_types:
         | 
| 10 | 
            +
              m1.small:
         | 
| 11 | 
            +
                memory: 1.7 GB
         | 
| 12 | 
            +
                processor: 1 ECU
         | 
| 13 | 
            +
                storage: 160 GB
         | 
| 14 | 
            +
                platform: 32-bit
         | 
| 15 | 
            +
                io_performance: Moderate
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              m1.large:
         | 
| 18 | 
            +
                memory: 7.5 GB
         | 
| 19 | 
            +
                processor: 4 ECUs
         | 
| 20 | 
            +
                storage: 850 GB
         | 
| 21 | 
            +
                platform: 64-bit
         | 
| 22 | 
            +
                io_performance: High
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              m1.xlarge:
         | 
| 25 | 
            +
                memory: 15 GB
         | 
| 26 | 
            +
                processor: 8 ECUs
         | 
| 27 | 
            +
                storage: 1,690 GB
         | 
| 28 | 
            +
                platform: 64-bit
         | 
| 29 | 
            +
                io_performance: High
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              t1.micro:
         | 
| 32 | 
            +
                memory: 613MB
         | 
| 33 | 
            +
                processor: Up to 2 ECUs
         | 
| 34 | 
            +
                storage: EBS storage only
         | 
| 35 | 
            +
                platform: 32-bit or 64-bit
         | 
| 36 | 
            +
                io_performance: Low
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              m2.xlarge:
         | 
| 39 | 
            +
                memory: 17.1 GB
         | 
| 40 | 
            +
                processor: 6.5 ECUs
         | 
| 41 | 
            +
                storage: 420 GB
         | 
| 42 | 
            +
                platform: 64-bit
         | 
| 43 | 
            +
                io_performance: Moderate
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              m2.2xlarge:
         | 
| 46 | 
            +
                memory: 34.2 GB
         | 
| 47 | 
            +
                processor: 13 ECUs
         | 
| 48 | 
            +
                storage: 850 GB
         | 
| 49 | 
            +
                platform: 64-bit
         | 
| 50 | 
            +
                io_performance: High
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              m2.4xlarge:
         | 
| 53 | 
            +
                memory: 68.4 GB
         | 
| 54 | 
            +
                processor: 26 ECUs
         | 
| 55 | 
            +
                storage: 1690 GB
         | 
| 56 | 
            +
                platform: 64-bit
         | 
| 57 | 
            +
                io_performance: High
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              c1.medium:
         | 
| 60 | 
            +
                memory: 1.7 GB
         | 
| 61 | 
            +
                processor: 5 ECUs
         | 
| 62 | 
            +
                storage: 350 GB
         | 
| 63 | 
            +
                platform: 32-bit
         | 
| 64 | 
            +
                io_performance: Moderate
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              c1.xlarge:
         | 
| 67 | 
            +
                memory: 7 GB
         | 
| 68 | 
            +
                processor: 20 ECUs
         | 
| 69 | 
            +
                storage: 1690 GB
         | 
| 70 | 
            +
                platform: 64-bit
         | 
| 71 | 
            +
                io_performance: High
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              cc1.4xlarge:
         | 
| 74 | 
            +
                memory: 23 GB
         | 
| 75 | 
            +
                processor: 33.5 ECUs
         | 
| 76 | 
            +
                storage: 1690 GB
         | 
| 77 | 
            +
                platform: 64-bit
         | 
| 78 | 
            +
                io_performance: Very High
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              cg1.4xlarge:
         | 
| 81 | 
            +
                memory: 22 GB
         | 
| 82 | 
            +
                processor: 33.5 ECUs
         | 
| 83 | 
            +
                storage: 1690 GB
         | 
| 84 | 
            +
                platform: 64-bit
         | 
| 85 | 
            +
                io_performance: Very High
         | 
| 86 | 
            +
             | 
| 87 | 
            +
            db_instance_types:
         | 
| 88 | 
            +
              db.m1.small:
         | 
| 89 | 
            +
                memory: 1.7 GB
         | 
| 90 | 
            +
                processor: 1 ECU
         | 
| 91 | 
            +
                platform: 64-bit
         | 
| 92 | 
            +
                io_performance: Moderate
         | 
| 93 | 
            +
             | 
| 94 | 
            +
              db.m1.large:
         | 
| 95 | 
            +
                memory: 7.5 GB
         | 
| 96 | 
            +
                processor: 4 ECUs
         | 
| 97 | 
            +
                platform: 64-bit
         | 
| 98 | 
            +
                io_performance: High
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              db.m1.xlarge:
         | 
| 101 | 
            +
                memory: 15 GB
         | 
| 102 | 
            +
                processor: 8 ECUs
         | 
| 103 | 
            +
                platform: 64-bit
         | 
| 104 | 
            +
                io_performance: High
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              db.m2.xlarge:
         | 
| 107 | 
            +
                memory: 17.1 GB
         | 
| 108 | 
            +
                processor: 6.5 ECU
         | 
| 109 | 
            +
                platform: 64-bit
         | 
| 110 | 
            +
                io_performance: High
         | 
| 111 | 
            +
             | 
| 112 | 
            +
              db.m2.2xlarge:
         | 
| 113 | 
            +
                memory: 34 GB
         | 
| 114 | 
            +
                processor: 13 ECUs
         | 
| 115 | 
            +
                platform: 64-bit
         | 
| 116 | 
            +
                io_performance: High
         | 
| 117 | 
            +
             | 
| 118 | 
            +
              db.m2.4xlarge:
         | 
| 119 | 
            +
                memory: 68 GB
         | 
| 120 | 
            +
                processor: 26 ECUs
         | 
| 121 | 
            +
                platform: 64-bit
         | 
| 122 | 
            +
                io_performance: High
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            require 'clamp'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Monkey patch clamp to remove duplicate options from help
         | 
| 4 | 
            +
            module Clamp::Option::Declaration
         | 
| 5 | 
            +
              alias_method :non_uniq_documented_options, :documented_options
         | 
| 6 | 
            +
              def documented_options
         | 
| 7 | 
            +
                non_uniq_documented_options.uniq
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
             | 
| 12 | 
            +
            class DewBaseCommand < Clamp::Command
         | 
| 13 | 
            +
              def configure
         | 
| 14 | 
            +
                $debug = debug?
         | 
| 15 | 
            +
                Inform.level = quiet? ? :warning : (verbose? ? :debug : :info)
         | 
| 16 | 
            +
                Cloud.region = region
         | 
| 17 | 
            +
                Cloud.account_name = account
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def execute
         | 
| 21 | 
            +
                configure
         | 
| 22 | 
            +
                super
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
    
        data/lib/dew/cloud.rb
    ADDED
    
    | @@ -0,0 +1,79 @@ | |
| 1 | 
            +
            class Cloud
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              attr_reader :region, :account_name, :profile_name
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              class << self
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def connect region, account_name, profile_name = nil
         | 
| 8 | 
            +
                  @connection = new(region, account_name, profile_name)
         | 
| 9 | 
            +
                  Inform.info("Connected to AWS in %{region} using account %{account_name}", :region => region, :account_name => account_name)
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def method_missing method, *args
         | 
| 13 | 
            +
                  @connection.send(method, *args)
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def account
         | 
| 19 | 
            +
                @account ||= Account.read(account_name)
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def compute
         | 
| 23 | 
            +
                @compute ||= Fog::Compute.new(fog_credentials.merge({:provider => 'AWS'}))
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              def security_groups
         | 
| 27 | 
            +
                @security_groups ||= compute.security_groups.inject({}) { |h, g| h[g.name] = g; h }
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def valid_servers
         | 
| 31 | 
            +
                @valid_servers ||= Cloud.compute.servers.select{ |s| %w{running pending}.include?(s.state) }
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def keypair_exists? keypair
         | 
| 35 | 
            +
                !!compute.key_pairs.get(keypair)
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def elb
         | 
| 39 | 
            +
                @elb ||= Fog::AWS::ELB.new(fog_credentials)
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              def rds
         | 
| 43 | 
            +
                @rds ||= Fog::AWS::RDS.new(fog_credentials)
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              def rds_authorized_ec2_owner_ids
         | 
| 47 | 
            +
                # XXX - Does this belong in Fog::AWS::RDS ?
         | 
| 48 | 
            +
                @rds_authorized_ec2_owner_ids ||= rds.security_groups.detect { |security_group|
         | 
| 49 | 
            +
                  security_group.id == 'default'
         | 
| 50 | 
            +
                }.ec2_security_groups.select { |ec2_security_group|
         | 
| 51 | 
            +
                  ec2_security_group["EC2SecurityGroupName"] == "default" && ec2_security_group["Status"] == "authorized"
         | 
| 52 | 
            +
                }.collect { |h|
         | 
| 53 | 
            +
                  h["EC2SecurityGroupOwnerId"]
         | 
| 54 | 
            +
                }
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              def profile
         | 
| 58 | 
            +
                if profile_name
         | 
| 59 | 
            +
                  @profile ||= Profile.read(profile_name)
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              def keyfile_path(key_name)
         | 
| 64 | 
            +
                account_dir = File.join(ENV['HOME'], '.dew','accounts')
         | 
| 65 | 
            +
                File.join(account_dir, 'keys', account_name, region, "#{key_name}.pem")
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              private
         | 
| 69 | 
            +
             | 
| 70 | 
            +
              def initialize region, account_name, profile_name = nil
         | 
| 71 | 
            +
                @region = region
         | 
| 72 | 
            +
                @account_name = account_name
         | 
| 73 | 
            +
                @profile_name = profile_name      
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              def fog_credentials
         | 
| 77 | 
            +
                {:region => region, :aws_access_key_id => account.aws_access_key_id, :aws_secret_access_key => account.aws_secret_access_key}
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
            end
         | 
    
        data/lib/dew/commands.rb
    ADDED
    
    
| @@ -0,0 +1,67 @@ | |
| 1 | 
            +
            require 'dew/controllers/amis_controller'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class AMIsCommand < Clamp::Command
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              def puppet_node_filename node_name
         | 
| 6 | 
            +
                File.join(ENV['HOME'], '.dew', 'puppet', 'manifests', 'nodes', "#{node_name}.pp")
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def controller
         | 
| 10 | 
            +
                @controller ||= AMIsController.new
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              default_subcommand "index", "Show AMIs" do
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def execute
         | 
| 16 | 
            +
                  controller.index
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              subcommand "show", "Show an AMI" do
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                parameter "AMI_NAME", "Name of AMI"
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def execute
         | 
| 26 | 
            +
                  controller.show(ami_name)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              subcommand "show", "Show an AMI" do
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                parameter "AMI_NAME", "Name of AMI"
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def execute
         | 
| 36 | 
            +
                  controller.show(ami_name)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              subcommand "create", "Create a new AMI" do
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                parameter "PUPPET_NODE_NAME", "Puppet node (in puppet/manifests/nodes/*.pp) to run on AMI" do |puppet_node_name|
         | 
| 44 | 
            +
                  unless File.exist?(puppet_node_filename(puppet_node_name))
         | 
| 45 | 
            +
                    raise ArgumentError, "Can't find puppet/#{puppet_node_filename(puppet_node_name)}: check that puppet submodule is checked out and node exists"
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                  puppet_node_name
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
                parameter "AMI_NAME", "What to call the newly created AMI"
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def execute
         | 
| 52 | 
            +
                  controller.create(ami_name, puppet_node_name)
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              subcommand "destroy", "Destroy an existing AMI" do
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                parameter "AMI_NAME", "Name of AMI to destroy"
         | 
| 60 | 
            +
                option ['-f', '--force'], :flag, "Don't ask for confirmation before destroying", :default => false
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def execute
         | 
| 63 | 
            +
                  controller.destroy(ami_name, :force => force?)
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            class ConsoleCommand < Clamp::Command
         | 
| 2 | 
            +
              def execute
         | 
| 3 | 
            +
                load File.expand_path(File.join(File.dirname(__FILE__), 'console', 'irb_override.rb'))
         | 
| 4 | 
            +
                ARGV.reject! { true }
         | 
| 5 | 
            +
                puts <<-EOS
         | 
| 6 | 
            +
            ===============================================================
         | 
| 7 | 
            +
            Objects available: -
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Cloud          - Cloud Handle
         | 
| 10 | 
            +
            Cloud.compute  - Access AWS EC2 (Elastic Compute Cloud) instances
         | 
| 11 | 
            +
            Cloud.elb      - Access AWS ELB (Elastic Load Balancers)
         | 
| 12 | 
            +
            Cloud.rds      - Access AWS RDS (Relational Database Service)
         | 
| 13 | 
            +
            ===============================================================
         | 
| 14 | 
            +
            EOS
         | 
| 15 | 
            +
                IRB.start_session(binding)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            require 'irb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module IRB # :nodoc:
         | 
| 4 | 
            +
              def self.start_session(binding)
         | 
| 5 | 
            +
                unless @__initialized
         | 
| 6 | 
            +
                  args = ARGV
         | 
| 7 | 
            +
                  ARGV.replace(ARGV.dup)
         | 
| 8 | 
            +
                  IRB.setup(nil)
         | 
| 9 | 
            +
                  ARGV.replace(args)
         | 
| 10 | 
            +
                  @__initialized = true
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                workspace = WorkSpace.new(binding)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                irb = Irb.new(workspace)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
         | 
| 18 | 
            +
                @CONF[:MAIN_CONTEXT] = irb.context
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                catch(:IRB_EXIT) do
         | 
| 21 | 
            +
                  irb.eval_input
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,114 @@ | |
| 1 | 
            +
            require 'dew/controllers/amis_controller'
         | 
| 2 | 
            +
            require 'erb' # XXX
         | 
| 3 | 
            +
            require 'ostruct' # XXX
         | 
| 4 | 
            +
            require 'open-uri' # XXX
         | 
| 5 | 
            +
            require 'json' # XXX
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class DeployCommand < Clamp::Command
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def template filename
         | 
| 10 | 
            +
                File.join(File.dirname(__FILE__), 'deploy', 'templates', filename)
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              subcommand 'passenger', "Deploy a Passenger-compatiable application to an environment" do
         | 
| 14 | 
            +
                parameter "APPLICATION_NAME", "Repository and application name"
         | 
| 15 | 
            +
                parameter "REVISION", "Git revision to deploy (tag, branch, or commit id)"
         | 
| 16 | 
            +
                parameter "ENVIRONMENT_NAME", "Environment to deploy into"
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                option ['--rails-env'], 'ENVIRONMENT', "Rails environment to use", :default => 'production'
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def execute
         | 
| 21 | 
            +
                  env = Environment.get(environment_name)
         | 
| 22 | 
            +
                  env.servers.each do |server|
         | 
| 23 | 
            +
                    Inform.info("Working with server %{id} of %{l} servers", :id => server.id, :l => env.servers.length)
         | 
| 24 | 
            +
                    env.remove_server_from_elb(server) if env.has_elb?
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    ssh = server.ssh
         | 
| 27 | 
            +
                    initial = !ssh.exist?(application_name)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    Inform.info("%{app} doesn't exist - initial install", :app => application_name) if initial
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    Inform.info("Stopping apache") do
         | 
| 32 | 
            +
                      ssh.run "sudo apache2ctl stop"
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    Inform.info("Obtaining version %{v} of %{app}", :v => revision, :app => application_name) do
         | 
| 36 | 
            +
                      if initial
         | 
| 37 | 
            +
                        Inform.debug("Writing out ~/.ssh/known_hosts file to allow github clone")
         | 
| 38 | 
            +
                        ssh.upload template('known_hosts'), ".ssh/known_hosts"
         | 
| 39 | 
            +
                        Inform.debug("Cloning %{app} in to ~/%{app}", :app => application_name)
         | 
| 40 | 
            +
                        ssh.run "git clone git@github.com:playup/#{application_name}.git #{application_name}"
         | 
| 41 | 
            +
                      else
         | 
| 42 | 
            +
                        Inform.debug("Updating %{app} repository",  :app => application_name)
         | 
| 43 | 
            +
                        ssh.run "cd #{application_name}; git fetch -q"
         | 
| 44 | 
            +
                      end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                      Inform.debug("Checking out version %{version}", :version => revision)
         | 
| 47 | 
            +
                      ssh.run "cd #{application_name} && git checkout -q -f origin/#{revision}"
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    cd_and_rvm = "cd #{application_name} && . /usr/local/rvm/scripts/rvm && rvm use ruby-1.9.2 && RAILS_ENV=#{rails_env} "
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    Inform.info("Updating/installing gems") do
         | 
| 53 | 
            +
                      ssh.run cd_and_rvm + "bundle install"
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    if ssh.exist?("#{application_name}/config/database.yml")
         | 
| 57 | 
            +
                      Inform.info("config/database.yml exists, creating and/or updating database") do
         | 
| 58 | 
            +
                        Inform.debug("Creating database") if initial
         | 
| 59 | 
            +
                        ssh.run cd_and_rvm + "rake db:create" if initial
         | 
| 60 | 
            +
                        Inform.debug("Updating database")
         | 
| 61 | 
            +
                        ssh.run cd_and_rvm + "rake db:migrate"
         | 
| 62 | 
            +
                      end
         | 
| 63 | 
            +
                    else
         | 
| 64 | 
            +
                      Inform.info("No config/database.yml, skipping database step")
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    Inform.info("Starting application with passenger") do
         | 
| 68 | 
            +
                      if ssh.exist?('/etc/apache2/sites-enabled/000-default')
         | 
| 69 | 
            +
                        Inform.debug("Disabling default apache site")
         | 
| 70 | 
            +
                        ssh.run "sudo a2dissite default"
         | 
| 71 | 
            +
                      end
         | 
| 72 | 
            +
                      Inform.debug("Uploading passenger config")
         | 
| 73 | 
            +
                      passenger_config = ERB.new(File.read template('apache.conf.erb')).result(OpenStruct.new(
         | 
| 74 | 
            +
                        :rails_env => rails_env,
         | 
| 75 | 
            +
                        :application_name => application_name,
         | 
| 76 | 
            +
                        :working_directory => "/home/ubuntu/#{application_name}"
         | 
| 77 | 
            +
                      ).instance_eval {binding})
         | 
| 78 | 
            +
                      ssh.write passenger_config, "/tmp/apache.conf"
         | 
| 79 | 
            +
                      ssh.run "sudo cp /tmp/apache.conf /etc/apache2/sites-available/#{application_name}"
         | 
| 80 | 
            +
                      ssh.run "sudo chmod 0644 /etc/apache2/sites-available/#{application_name}" # yeah, I don't know why it gets written as 0600
         | 
| 81 | 
            +
                      unless ssh.exist?('/etc/apache2/sites-enabled/#{application_name}')
         | 
| 82 | 
            +
                        Inform.debug("Enabling passenger site in apache")
         | 
| 83 | 
            +
                        ssh.run "sudo a2ensite #{application_name}"
         | 
| 84 | 
            +
                      end
         | 
| 85 | 
            +
                      Inform.debug("Restarting apache")
         | 
| 86 | 
            +
                      ssh.run "sudo apache2ctl restart"
         | 
| 87 | 
            +
                    end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                    status_url = "http://#{server.public_ip_address}/status"
         | 
| 90 | 
            +
                    Inform.info("Checking status URL at %{u}", :u => status_url) do
         | 
| 91 | 
            +
                      response = JSON.parse(open(status_url).read)
         | 
| 92 | 
            +
                      unless response.include?('status') && response['status'] == 'OK'
         | 
| 93 | 
            +
                        raise "Did not receive an OK status response."
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
                    end
         | 
| 96 | 
            +
                    env.add_server_to_elb(server) if env.has_elb?
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
              subcommand 'puge', "Deploy PUGE" do
         | 
| 103 | 
            +
                parameter "TAG", "Git revision to deploy (tag, branch, or commit id)"
         | 
| 104 | 
            +
                parameter "ENVIRONMENT_NAME", "Environment to deploy into"
         | 
| 105 | 
            +
                parameter "RAILS_ENV", "Rails environment used for db setup"
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                def execute
         | 
| 108 | 
            +
                  Inform.info("Deploying PUGE tag %{tag} using RAILS_ENV %{rails_env} to environment %{environment_name}", :tag => tag, :rails_env => rails_env, :environment_name => environment_name)
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  DeployController.new.create('puge', environment_name, { 'tag' => tag, 'rails_env' => rails_env })
         | 
| 111 | 
            +
                  Inform.info("Deployed successfully.")
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
            end
         |