conan_deploy_stackato3 0.1.1
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.
- checksums.yaml +15 -0
 - data/README.md +223 -0
 - data/bin/conan-stackato3 +131 -0
 - data/lib/conan/application.rb +113 -0
 - data/lib/conan/application_helper.rb +120 -0
 - data/lib/conan/deploy.rb +41 -0
 - data/lib/conan/deployment.rb +91 -0
 - data/lib/conan/environment.rb +24 -0
 - data/lib/conan/has_options.rb +15 -0
 - data/lib/conan/jvm_app.rb +16 -0
 - data/lib/conan/manifest.rb +100 -0
 - data/lib/conan/manifest_builder.rb +14 -0
 - data/lib/conan/newrelic.rb +16 -0
 - data/lib/conan/options.rb +31 -0
 - data/lib/conan/output.rb +180 -0
 - data/lib/conan/pipeline.rb +102 -0
 - data/lib/conan/rails_zip_app.rb +10 -0
 - data/lib/conan/repository.rb +95 -0
 - data/lib/conan/stackato.rb +105 -0
 - data/lib/conan/templates.rb +38 -0
 - data/lib/conan/version.rb +3 -0
 - metadata +78 -0
 
| 
         @@ -0,0 +1,91 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'conan/has_options'
         
     | 
| 
      
 2 
     | 
    
         
            +
            class Deployment < HasOptions
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              attr_accessor :environment, :org, :ship, :shipcloud, :app_ids, :facility_id, :additional_mappings, :custom_smoke_test_path
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def initialize(environment, org, ship)
         
     | 
| 
      
 7 
     | 
    
         
            +
                # inherit options from the environment
         
     | 
| 
      
 8 
     | 
    
         
            +
                #super(environment.options)  # TODO:  copy?!
         
     | 
| 
      
 9 
     | 
    
         
            +
                super({})
         
     | 
| 
      
 10 
     | 
    
         
            +
                @environment = environment
         
     | 
| 
      
 11 
     | 
    
         
            +
                @org = org
         
     | 
| 
      
 12 
     | 
    
         
            +
                @ship = ship
         
     | 
| 
      
 13 
     | 
    
         
            +
                @shipcloud = "#{org}-#{ship}"
         
     | 
| 
      
 14 
     | 
    
         
            +
                @app_ids = []
         
     | 
| 
      
 15 
     | 
    
         
            +
                @additional_mappings = []
         
     | 
| 
      
 16 
     | 
    
         
            +
                @facility_id = nil
         
     | 
| 
      
 17 
     | 
    
         
            +
                @enabled = true
         
     | 
| 
      
 18 
     | 
    
         
            +
                @randomid = SecureRandom.hex(3)
         
     | 
| 
      
 19 
     | 
    
         
            +
                @custom_smoke_test_path = nil
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def apps(*app_ids)
         
     | 
| 
      
 23 
     | 
    
         
            +
                @app_ids = app_ids
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def facility(facility_id)
         
     | 
| 
      
 27 
     | 
    
         
            +
                @facility_id = facility_id
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def hostnames(*hostnames)
         
     | 
| 
      
 31 
     | 
    
         
            +
                hostnames.each do |hostname|
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @additional_mappings.push(hostname) unless hostname.empty?
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def enabled(b)
         
     | 
| 
      
 37 
     | 
    
         
            +
                @enabled = b
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def enabled?
         
     | 
| 
      
 41 
     | 
    
         
            +
                @enabled
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              def name(app)
         
     | 
| 
      
 45 
     | 
    
         
            +
                "#{app.id}-#{@environment.id}-#{@ship}"
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              def unique_name(app)
         
     | 
| 
      
 49 
     | 
    
         
            +
                "#{name(app)}-#{@randomid}"
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              def dns_name(app)
         
     | 
| 
      
 53 
     | 
    
         
            +
                "#{@environment.id}.#{app.url_segment}.#{@ship}.#{@org}.mtnsatcloud.com"
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              def agnostic_dns_name(app)
         
     | 
| 
      
 57 
     | 
    
         
            +
                "#{app.url_segment}.mtnsat.io"
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              def active_urls(app)
         
     | 
| 
      
 61 
     | 
    
         
            +
                [ dns_name(app), agnostic_dns_name(app) ] + @additional_mappings
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              def inactive_urls(app)
         
     | 
| 
      
 65 
     | 
    
         
            +
                active_urls(app).map{ |url| "x.#{url}" }
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              def manifest_url(app)
         
     | 
| 
      
 69 
     | 
    
         
            +
                "http://#{dns_name(app)}/status/manifest"
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              def active_smoke_test_url(app)
         
     | 
| 
      
 73 
     | 
    
         
            +
                "http://#{dns_name(app)}/#{@custom_smoke_test_path || 'status/healthcheck'}"
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              def inactive_smoke_test_url(app)
         
     | 
| 
      
 77 
     | 
    
         
            +
                "http://x.#{dns_name(app)}/#{@custom_smoke_test_path || 'status/healthcheck'}"
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              def paas_target
         
     | 
| 
      
 81 
     | 
    
         
            +
                "https://api.paasv2.#{@ship}.#{@org}.mtnsatcloud.com"
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
              def to_s
         
     | 
| 
      
 85 
     | 
    
         
            +
                "#{org}-#{ship}"
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              def smoke_test_path(path=nil)
         
     | 
| 
      
 89 
     | 
    
         
            +
                @custom_smoke_test_path = path
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Environment
         
     | 
| 
      
 2 
     | 
    
         
            +
              attr_accessor :id, :upstream_env, :deployments
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize(env_id)
         
     | 
| 
      
 5 
     | 
    
         
            +
                @id = env_id
         
     | 
| 
      
 6 
     | 
    
         
            +
                @deployments = []
         
     | 
| 
      
 7 
     | 
    
         
            +
                @org_holder = nil
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def promotes_from(env_id)
         
     | 
| 
      
 11 
     | 
    
         
            +
                @upstream_env = env_id
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def org(org_name, &block)
         
     | 
| 
      
 15 
     | 
    
         
            +
                @org_holder = org_name
         
     | 
| 
      
 16 
     | 
    
         
            +
                self.instance_eval(&block)
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def deploy(ship, &block)
         
     | 
| 
      
 20 
     | 
    
         
            +
                d = Deployment.new(self, @org_holder, ship)
         
     | 
| 
      
 21 
     | 
    
         
            +
                d.instance_eval(&block)
         
     | 
| 
      
 22 
     | 
    
         
            +
                @deployments << d
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'conan/application'
         
     | 
| 
      
 2 
     | 
    
         
            +
            class JvmApp < Application
         
     | 
| 
      
 3 
     | 
    
         
            +
              attr_accessor :sha1, :artifact_repo
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def initialize(id, project_name, artifact_repo, options, url_segment=nil)
         
     | 
| 
      
 6 
     | 
    
         
            +
                super(id, project_name, :jvm, options, url_segment)
         
     | 
| 
      
 7 
     | 
    
         
            +
                @sha1 = nil
         
     | 
| 
      
 8 
     | 
    
         
            +
                @artifact_repo = artifact_repo
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def download(location)
         
     | 
| 
      
 12 
     | 
    
         
            +
                super
         
     | 
| 
      
 13 
     | 
    
         
            +
                puts "- Provision NewRelic Agent jar"
         
     | 
| 
      
 14 
     | 
    
         
            +
                @artifact_repo.downloadNewRelicAgent(File.join(location, @artifact_id), '3.2.3', 'c07cd82e033af9628cd7f90df874daee7000e471')
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,100 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Manifest
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              def initialize(options, artifact_repo, output)
         
     | 
| 
      
 4 
     | 
    
         
            +
                @pipelines = {}
         
     | 
| 
      
 5 
     | 
    
         
            +
                @environments = {}
         
     | 
| 
      
 6 
     | 
    
         
            +
                @options = options
         
     | 
| 
      
 7 
     | 
    
         
            +
                @artifact_repo = artifact_repo
         
     | 
| 
      
 8 
     | 
    
         
            +
                @output = output
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              # select a pipeline and environment to do operations on
         
     | 
| 
      
 12 
     | 
    
         
            +
              def select(pipeline_id, env_id)
         
     | 
| 
      
 13 
     | 
    
         
            +
                env = @environments[env_id]
         
     | 
| 
      
 14 
     | 
    
         
            +
                raise ArgumentError.new "Invalid environment id: '#{env_id}'. Valid options are #{@environments.keys.join(", ")}" if env.nil?
         
     | 
| 
      
 15 
     | 
    
         
            +
                @current_environment = env
         
     | 
| 
      
 16 
     | 
    
         
            +
                pl = @pipelines[pipeline_id]
         
     | 
| 
      
 17 
     | 
    
         
            +
                raise ArgumentError.new "Invalid pipeline id: '#{pipeline_id}'. Valid options are #{@pipelines.keys.join(", ")}" if pl.nil?
         
     | 
| 
      
 18 
     | 
    
         
            +
                @current_pipeline = pl
         
     | 
| 
      
 19 
     | 
    
         
            +
                pl.load!(env, @options[:'deploy-shipcloud'])
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def pipeline(pipeline_id, &block)
         
     | 
| 
      
 23 
     | 
    
         
            +
                pl = Pipeline.new(pipeline_id, @artifact_repo, @output, @options)
         
     | 
| 
      
 24 
     | 
    
         
            +
                pl.instance_eval(&block)
         
     | 
| 
      
 25 
     | 
    
         
            +
                @pipelines[pipeline_id] = pl
         
     | 
| 
      
 26 
     | 
    
         
            +
                pl
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              def environment(env_id, &block)
         
     | 
| 
      
 30 
     | 
    
         
            +
                e = Environment.new(env_id)
         
     | 
| 
      
 31 
     | 
    
         
            +
                e.instance_eval(&block)
         
     | 
| 
      
 32 
     | 
    
         
            +
                @environments[env_id] = e
         
     | 
| 
      
 33 
     | 
    
         
            +
                e
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def appVersion(pipeline_id, app_id)
         
     | 
| 
      
 37 
     | 
    
         
            +
                @pipelines[pipeline_id].appVersion(app_id)
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def provision
         
     | 
| 
      
 41 
     | 
    
         
            +
                validateThatEnvironmentIsSelected
         
     | 
| 
      
 42 
     | 
    
         
            +
                # TODO banners
         
     | 
| 
      
 43 
     | 
    
         
            +
                puts "Update #{@current_environment.id} manifest files for #{@current_pipeline.id} pipeline"
         
     | 
| 
      
 44 
     | 
    
         
            +
                @current_pipeline.update(@current_environment, @environments[@current_environment.upstream_env])
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              def configure
         
     | 
| 
      
 48 
     | 
    
         
            +
                validateThatEnvironmentIsSelected
         
     | 
| 
      
 49 
     | 
    
         
            +
                puts "Configure #{@current_environment.id} manifest files for #{@current_pipeline.id} pipeline"
         
     | 
| 
      
 50 
     | 
    
         
            +
                @current_pipeline.configure(@current_environment)
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              def bg_configure
         
     | 
| 
      
 54 
     | 
    
         
            +
                validateThatEnvironmentIsSelected
         
     | 
| 
      
 55 
     | 
    
         
            +
                puts "Blue/green configure #{@current_environment.id} manifest files for #{@current_pipeline.id} pipeline"
         
     | 
| 
      
 56 
     | 
    
         
            +
                @current_pipeline.configure(@current_environment, true)
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              def paas
         
     | 
| 
      
 60 
     | 
    
         
            +
                paas_user = @options[:'paas-user'] || ENV['PAAS_USER']
         
     | 
| 
      
 61 
     | 
    
         
            +
                paas_pwd = @options[:'paas-password'] || ENV['PAAS_PASSWORD']
         
     | 
| 
      
 62 
     | 
    
         
            +
                paas_space = @options[:'paas-space'] || ENV['PAAS_SPACE']
         
     | 
| 
      
 63 
     | 
    
         
            +
                dry_run = @options[:'dry-run'] || false
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                Stackato.new(paas_user, paas_pwd, paas_space, dry_run)
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              def deploy
         
     | 
| 
      
 69 
     | 
    
         
            +
                validateThatEnvironmentIsSelected
         
     | 
| 
      
 70 
     | 
    
         
            +
                puts "Deploy #{@current_environment.id} for #{@current_pipeline.id} pipeline"
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                nr_api_key = @options[:'new-relic-api-key'] || ENV['NEWRELIC_API_KEY']
         
     | 
| 
      
 73 
     | 
    
         
            +
                force = @options[:'force-deploy'] || false
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                @current_pipeline.deploy(@current_environment, paas, force) { |app_name|
         
     | 
| 
      
 76 
     | 
    
         
            +
                  if (nr_api_key)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    puts 'Reporting Deployment to New Relic'
         
     | 
| 
      
 78 
     | 
    
         
            +
                    job = @options[:'job-url'] || 'nexus-app-manifest'
         
     | 
| 
      
 79 
     | 
    
         
            +
                    NewRelic.alertDeployment(nr_api_key, app_name, "Deployed by #{job}")
         
     | 
| 
      
 80 
     | 
    
         
            +
                  else
         
     | 
| 
      
 81 
     | 
    
         
            +
                    puts "WARNING: Skipping New Relic alert. No API defined"
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
                }
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
              def bg_deploy
         
     | 
| 
      
 87 
     | 
    
         
            +
                validateThatEnvironmentIsSelected
         
     | 
| 
      
 88 
     | 
    
         
            +
                puts "Blue/green deploy #{@current_environment.id} for #{@current_pipeline.id} pipeline"
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                force = @options[:'force-deploy'] || false
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                @current_pipeline.bg_deploy(@current_environment, paas, force)
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
              def validateThatEnvironmentIsSelected
         
     | 
| 
      
 96 
     | 
    
         
            +
                unless @current_environment && @current_pipeline
         
     | 
| 
      
 97 
     | 
    
         
            +
                  raise ScriptError, 'Environment and Pipeline must be selected'
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ManifestBuilder
         
     | 
| 
      
 2 
     | 
    
         
            +
              def self.build(options, artifact_repo=nil, outthingy=nil, &block)
         
     | 
| 
      
 3 
     | 
    
         
            +
                manifest_dir = options[:directory]
         
     | 
| 
      
 4 
     | 
    
         
            +
                output_type = options[:format]
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                artifact_repo ||= DefaultArtifactRepository.new
         
     | 
| 
      
 7 
     | 
    
         
            +
                outthingy ||= StackatoOutThingy.new(manifest_dir)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                manifest = Manifest.new(options, artifact_repo, outthingy)
         
     | 
| 
      
 10 
     | 
    
         
            +
                manifest.instance_eval(&block)
         
     | 
| 
      
 11 
     | 
    
         
            +
                manifest.select(options[:pipeline], options[:environment])
         
     | 
| 
      
 12 
     | 
    
         
            +
                manifest
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rest_client'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module NewRelic
         
     | 
| 
      
 4 
     | 
    
         
            +
              def self.alertDeployment(api_key, app_name, description)    
         
     | 
| 
      
 5 
     | 
    
         
            +
                response = RestClient.post(
         
     | 
| 
      
 6 
     | 
    
         
            +
                  'https://api.newrelic.com/deployments.xml',
         
     | 
| 
      
 7 
     | 
    
         
            +
                  :params => {
         
     | 
| 
      
 8 
     | 
    
         
            +
                    :'deployment[app_name]' => app_name, 
         
     | 
| 
      
 9 
     | 
    
         
            +
                    :'deployment[description]' => description
         
     | 
| 
      
 10 
     | 
    
         
            +
                  },
         
     | 
| 
      
 11 
     | 
    
         
            +
                  :headers => { 'x-api-key' => api_key }
         
     | 
| 
      
 12 
     | 
    
         
            +
                )
         
     | 
| 
      
 13 
     | 
    
         
            +
                puts response
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'conan/version'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Conan
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Options
         
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(options = {})
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @options = defaults.merge(options)
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def []=(k, v)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @options[k] = v
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def [](k)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @options[k]
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @options.to_s
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              private
         
     | 
| 
      
 22 
     | 
    
         
            +
                def defaults
         
     | 
| 
      
 23 
     | 
    
         
            +
                  {
         
     | 
| 
      
 24 
     | 
    
         
            +
                    :version => Conan::VERSION,
         
     | 
| 
      
 25 
     | 
    
         
            +
                    :directory  => Dir.pwd,
         
     | 
| 
      
 26 
     | 
    
         
            +
                    :format => :stackato,
         
     | 
| 
      
 27 
     | 
    
         
            +
                    :action => :provision
         
     | 
| 
      
 28 
     | 
    
         
            +
                  }
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/conan/output.rb
    ADDED
    
    | 
         @@ -0,0 +1,180 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'daphne_util'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'conan/templates'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class OutThingy
         
     | 
| 
      
 5 
     | 
    
         
            +
              attr_accessor :output_dir, :time
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def initialize(output_dir)
         
     | 
| 
      
 8 
     | 
    
         
            +
                @output_dir = output_dir
         
     | 
| 
      
 9 
     | 
    
         
            +
                @time = Time.new
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def outputToFile(file, &block)
         
     | 
| 
      
 13 
     | 
    
         
            +
                o = File.join(@output_dir, file)
         
     | 
| 
      
 14 
     | 
    
         
            +
                puts "Write: #{o}"
         
     | 
| 
      
 15 
     | 
    
         
            +
                FileUtils.mkdir_p File.dirname(o)
         
     | 
| 
      
 16 
     | 
    
         
            +
                File.open(o, 'w') { |f| yield f }
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def loadAppMetadataFromDeploymentIfExists(app, deploy)
         
     | 
| 
      
 20 
     | 
    
         
            +
                loadAppMetadataFromDeployment(app, deploy, true)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            class StackatoOutThingy < OutThingy
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              attr_accessor :environments_dir, :apps_dir
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              @@stackato_file_name = "stackato.yml"
         
     | 
| 
      
 29 
     | 
    
         
            +
              @@metadata_file_name = "metadata.xml"
         
     | 
| 
      
 30 
     | 
    
         
            +
              @environments_dir = nil
         
     | 
| 
      
 31 
     | 
    
         
            +
              @apps_dir = nil
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def initialize(output_dir)
         
     | 
| 
      
 34 
     | 
    
         
            +
                super(output_dir)
         
     | 
| 
      
 35 
     | 
    
         
            +
                workdir = File.join(output_dir,'tmp')
         
     | 
| 
      
 36 
     | 
    
         
            +
                @environments_dir = File.join(output_dir,'environments')
         
     | 
| 
      
 37 
     | 
    
         
            +
                @apps_dir = File.join(workdir,'apps')
         
     | 
| 
      
 38 
     | 
    
         
            +
                FileUtils.mkdir_p environments_dir
         
     | 
| 
      
 39 
     | 
    
         
            +
                FileUtils.mkdir_p apps_dir
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              def clean(app, environment)
         
     | 
| 
      
 43 
     | 
    
         
            +
                #  TODO: cleanup
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              def provision(app)
         
     | 
| 
      
 47 
     | 
    
         
            +
                app.download(@apps_dir)
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              def filePath(app, deploy)
         
     | 
| 
      
 51 
     | 
    
         
            +
                "#{deploy.environment.id}/#{deploy.shipcloud}/#{app.id}"
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              def workingDir(app)
         
     | 
| 
      
 55 
     | 
    
         
            +
                File.join(apps_dir, app.artifact_id)
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
              # TODO this needs a refactor, it's knoted up with App
         
     | 
| 
      
 59 
     | 
    
         
            +
              def loadAppMetadataFromDeployment(app, deploy, fail_silent=false)
         
     | 
| 
      
 60 
     | 
    
         
            +
                p = filePath(app, deploy)
         
     | 
| 
      
 61 
     | 
    
         
            +
                path = File.join(@environments_dir, p)
         
     | 
| 
      
 62 
     | 
    
         
            +
                metadata_file = File.join(path, @@metadata_file_name)
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                if (File.exists? path)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  File.open(metadata_file, 'r') { |f| app.readArtifactMetadata(f.read) }
         
     | 
| 
      
 66 
     | 
    
         
            +
                else
         
     | 
| 
      
 67 
     | 
    
         
            +
                  raise "Build meta-data was not found: #{path}" unless fail_silent
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              def writeArtifactMetadata(app, deploy)
         
     | 
| 
      
 72 
     | 
    
         
            +
                if (deploy.enabled?)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  path = filePath(app, deploy)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  outputToFile("environments/#{path}/#{@@metadata_file_name}") { |f|
         
     | 
| 
      
 75 
     | 
    
         
            +
                    f.write(app.artifact_meta_data)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  }
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              def writeConfiguration(app, deploy, bg=false)
         
     | 
| 
      
 81 
     | 
    
         
            +
                if (deploy.enabled?)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  target_dir = workingDir(app)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  templates_dir = File.join(target_dir, "deploy-templates")
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  daphne_tokens = [ "#{app.id}", "#{deploy.environment.id}" ]
         
     | 
| 
      
 86 
     | 
    
         
            +
                  daphne_tokens = daphne_tokens << "facility-#{deploy.facility_id}" unless deploy.facility_id.nil?
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  n_changes = Templates.evaluate templates_dir, target_dir, {
         
     | 
| 
      
 89 
     | 
    
         
            +
                    :app => app,
         
     | 
| 
      
 90 
     | 
    
         
            +
                    :deploy => deploy,
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                    #daphne, generate oauth app tokens
         
     | 
| 
      
 93 
     | 
    
         
            +
                    #TODO: seems like this should be refactored
         
     | 
| 
      
 94 
     | 
    
         
            +
                    :oauth_id => DaphneUtil.generate_id(*daphne_tokens),
         
     | 
| 
      
 95 
     | 
    
         
            +
                    :oauth_secret => DaphneUtil.generate_secret(*daphne_tokens),
         
     | 
| 
      
 96 
     | 
    
         
            +
                    :api_key => DaphneUtil.generate_api_key(*daphne_tokens),
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                    # short-cuts
         
     | 
| 
      
 99 
     | 
    
         
            +
                    :app_id => app.id,
         
     | 
| 
      
 100 
     | 
    
         
            +
                    :deploy_base_name => deploy.name(app),
         
     | 
| 
      
 101 
     | 
    
         
            +
                    :deploy_name => bg ? deploy.unique_name(app) : deploy.name(app),
         
     | 
| 
      
 102 
     | 
    
         
            +
                    :deploy_urls => bg ? deploy.inactive_urls(app) : deploy.active_urls(app),
         
     | 
| 
      
 103 
     | 
    
         
            +
                    :env => deploy.environment.id,
         
     | 
| 
      
 104 
     | 
    
         
            +
                    :org => deploy.org,
         
     | 
| 
      
 105 
     | 
    
         
            +
                    :ship => deploy.ship,
         
     | 
| 
      
 106 
     | 
    
         
            +
                    :infra => deploy.shipcloud, # TODO: remove infra key, this is just to avoid breaking existing templates
         
     | 
| 
      
 107 
     | 
    
         
            +
                    :shipcloud => deploy.shipcloud,
         
     | 
| 
      
 108 
     | 
    
         
            +
                    :facility => deploy.facility_id,
         
     | 
| 
      
 109 
     | 
    
         
            +
                    :options => deploy.options
         
     | 
| 
      
 110 
     | 
    
         
            +
                  }
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
                #TODO: can this be used to provide idempotency for config-only deploymnent?
         
     | 
| 
      
 113 
     | 
    
         
            +
                puts "#{n_changes} files changed"
         
     | 
| 
      
 114 
     | 
    
         
            +
              end
         
     | 
| 
      
 115 
     | 
    
         
            +
            end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            class PropertiesFileOutThingy < OutThingy
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
              def clean(app, environment)
         
     | 
| 
      
 120 
     | 
    
         
            +
                # cleanup current
         
     | 
| 
      
 121 
     | 
    
         
            +
                FileUtils.rm Dir.glob("#{@output_dir}/#{app.id}-deploy-#{environment.id}-*.properties")
         
     | 
| 
      
 122 
     | 
    
         
            +
              end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
              def fileName(app, deploy)
         
     | 
| 
      
 125 
     | 
    
         
            +
                "#{app.id}-deploy-#{deploy.environment.id}-#{deploy.shipcloud}.properties"
         
     | 
| 
      
 126 
     | 
    
         
            +
              end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
              def loadAppMetadataFromDeployment(app, deploy, fail_silent=false)
         
     | 
| 
      
 129 
     | 
    
         
            +
                path = File.join(@output_dir, fileName(app, deploy))
         
     | 
| 
      
 130 
     | 
    
         
            +
                if (File.exists? path)
         
     | 
| 
      
 131 
     | 
    
         
            +
                  props = Utils::Properties.load_from_file(path, true)
         
     | 
| 
      
 132 
     | 
    
         
            +
                  app.version = props.get(:DEPLOY_VERSION) # TODO: preserve SHA1
         
     | 
| 
      
 133 
     | 
    
         
            +
                else
         
     | 
| 
      
 134 
     | 
    
         
            +
                  raise "File not found: #{path}" unless fail_silent
         
     | 
| 
      
 135 
     | 
    
         
            +
                end
         
     | 
| 
      
 136 
     | 
    
         
            +
              end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
              def writeArtifactMetadata(app, deploy)
         
     | 
| 
      
 139 
     | 
    
         
            +
                file_name = fileName(app, deploy)
         
     | 
| 
      
 140 
     | 
    
         
            +
                out_file = File.join(@output_dir, file_name)
         
     | 
| 
      
 141 
     | 
    
         
            +
                if (!deploy.enabled?)
         
     | 
| 
      
 142 
     | 
    
         
            +
                  if (File.exists? out_file)
         
     | 
| 
      
 143 
     | 
    
         
            +
                    File.delete(out_file)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
                  out_file = File.join(@output_dir, "DISABLED-#{file_name}")
         
     | 
| 
      
 146 
     | 
    
         
            +
                end
         
     | 
| 
      
 147 
     | 
    
         
            +
                puts "Write: #{out_file}"
         
     | 
| 
      
 148 
     | 
    
         
            +
                File.open(out_file, 'w') { |f|
         
     | 
| 
      
 149 
     | 
    
         
            +
                  # TODO: would like @time in the manifest as audit field, but not sure it's such a good idea yet
         
     | 
| 
      
 150 
     | 
    
         
            +
                  # f << "\# #{file_name}\n\# #{@time}\n"
         
     | 
| 
      
 151 
     | 
    
         
            +
                  f << "\# #{file_name}\n"
         
     | 
| 
      
 152 
     | 
    
         
            +
                  f << "DEPLOY_ENV=#{deploy.environment.id}\n"
         
     | 
| 
      
 153 
     | 
    
         
            +
                  f << "DEPLOY_INFRA=#{deploy.shipcloud}\n"
         
     | 
| 
      
 154 
     | 
    
         
            +
                  if (deploy.facility_id)
         
     | 
| 
      
 155 
     | 
    
         
            +
                    f << "FACILITY=facility-#{deploy.facility_id}\n"
         
     | 
| 
      
 156 
     | 
    
         
            +
                  end
         
     | 
| 
      
 157 
     | 
    
         
            +
                  unless (deploy.options.empty?)
         
     | 
| 
      
 158 
     | 
    
         
            +
                    options = []
         
     | 
| 
      
 159 
     | 
    
         
            +
                    deploy.options.each do |k, v|
         
     | 
| 
      
 160 
     | 
    
         
            +
                      options << k + '|' + v.join(',')
         
     | 
| 
      
 161 
     | 
    
         
            +
                    end
         
     | 
| 
      
 162 
     | 
    
         
            +
                    p options.join(';')
         
     | 
| 
      
 163 
     | 
    
         
            +
                    f << "OPTIONS=#{options.join(';')}\n"
         
     | 
| 
      
 164 
     | 
    
         
            +
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
                  f << "APP=#{app.id}\n"
         
     | 
| 
      
 166 
     | 
    
         
            +
                  f << "DEPLOY_SHA1=#{app.sha1}\n"
         
     | 
| 
      
 167 
     | 
    
         
            +
                  f << "DEPLOY_VERSION=#{app.version}\n"
         
     | 
| 
      
 168 
     | 
    
         
            +
                  f << "TYPE=#{app.platform_type}\n"
         
     | 
| 
      
 169 
     | 
    
         
            +
                  f << "\n"
         
     | 
| 
      
 170 
     | 
    
         
            +
                }
         
     | 
| 
      
 171 
     | 
    
         
            +
              end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
              def provision(app)
         
     | 
| 
      
 174 
     | 
    
         
            +
                #noop
         
     | 
| 
      
 175 
     | 
    
         
            +
              end
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
              def writeConfiguration(app, deploy)
         
     | 
| 
      
 178 
     | 
    
         
            +
                # noop
         
     | 
| 
      
 179 
     | 
    
         
            +
              end
         
     | 
| 
      
 180 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,102 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Pipeline
         
     | 
| 
      
 2 
     | 
    
         
            +
              include ApiHelper
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              attr_accessor :id, :apps
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def initialize(id, artifact_repo, output, options)
         
     | 
| 
      
 7 
     | 
    
         
            +
                @id = id
         
     | 
| 
      
 8 
     | 
    
         
            +
                @artifact_repo = artifact_repo
         
     | 
| 
      
 9 
     | 
    
         
            +
                @output = output
         
     | 
| 
      
 10 
     | 
    
         
            +
                @apps = {}
         
     | 
| 
      
 11 
     | 
    
         
            +
                @options = options
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def app(app_id, project_name, platform_type, url_segment=nil)
         
     | 
| 
      
 15 
     | 
    
         
            +
                if (@options[:'deploy-app-name'].nil?) || (@options[:'deploy-app-name'] == app_id.to_s)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  puts "No app specified, or we matched the specified app: #{@options[:'deploy-app-name']}"
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @apps[app_id] = case platform_type
         
     | 
| 
      
 18 
     | 
    
         
            +
                    when :jvm
         
     | 
| 
      
 19 
     | 
    
         
            +
                      JvmApp.new(app_id, project_name, @artifact_repo, @options, url_segment)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    when :rails_zip
         
     | 
| 
      
 21 
     | 
    
         
            +
                      RailsZipApp.new(app_id, project_name, @artifact_repo, @options, url_segment)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    else
         
     | 
| 
      
 23 
     | 
    
         
            +
                      raise "unknown platform type: #{platform_type}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                else
         
     | 
| 
      
 26 
     | 
    
         
            +
                  puts "App #{app_id} doesn't match specified app #{@options[:'deploy-app-name']}, skipping"
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def appVersion(app_id)
         
     | 
| 
      
 31 
     | 
    
         
            +
                @apps[app_id].version
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              def load!(environment, deploy_shipcloud)
         
     | 
| 
      
 35 
     | 
    
         
            +
                eachAppDeployment(environment) { |app, deploy|
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # load the persisted meta-data
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @output.loadAppMetadataFromDeploymentIfExists(app, deploy)
         
     | 
| 
      
 38 
     | 
    
         
            +
                }
         
     | 
| 
      
 39 
     | 
    
         
            +
                @deploy_shipcloud = deploy_shipcloud
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              def update(environment, from_upstream_env)
         
     | 
| 
      
 43 
     | 
    
         
            +
                @apps.values.each { |app|
         
     | 
| 
      
 44 
     | 
    
         
            +
                  puts ''
         
     | 
| 
      
 45 
     | 
    
         
            +
                  if !(@options[:'deploy-app-version'].nil?)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    puts "Using version from options: #{@options[:'deploy-app-version']}"
         
     | 
| 
      
 47 
     | 
    
         
            +
                    app.findRequestedVersion(@options[:'deploy-app-version'])
         
     | 
| 
      
 48 
     | 
    
         
            +
                  elsif (from_upstream_env)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    # promote versions from an upstream deploy
         
     | 
| 
      
 50 
     | 
    
         
            +
                    # TODO: this needs improving
         
     | 
| 
      
 51 
     | 
    
         
            +
                    puts "Promote #{app.id} from #{from_upstream_env.id} to #{environment.id}"
         
     | 
| 
      
 52 
     | 
    
         
            +
                    upstream_deploy = from_upstream_env.deployments.select { |d| d.app_ids.select {|x| x == app.id }.size > 0 }.first
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @output.loadAppMetadataFromDeployment(app, upstream_deploy)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  else
         
     | 
| 
      
 55 
     | 
    
         
            +
                    puts "Find latest #{app.artifact_id}"
         
     | 
| 
      
 56 
     | 
    
         
            +
                    # lookup most recent from repo
         
     | 
| 
      
 57 
     | 
    
         
            +
                    app.findRequestedVersion('LATEST')
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  @output.clean(app, environment)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  # download artifacts
         
     | 
| 
      
 61 
     | 
    
         
            +
                  @output.provision(app)
         
     | 
| 
      
 62 
     | 
    
         
            +
                }
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                # write out deployment artifact meta-data
         
     | 
| 
      
 65 
     | 
    
         
            +
                eachAppDeployment(environment) { |app, deploy| @output.writeArtifactMetadata(app, deploy) }
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              def configure(environment, bg=false)
         
     | 
| 
      
 69 
     | 
    
         
            +
                eachAppDeployment(environment) { |app, deploy| @output.writeConfiguration(app, deploy, bg) }
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              def deploy(environment, paas, force=false)
         
     | 
| 
      
 73 
     | 
    
         
            +
                eachAppDeployment(environment) { |app, deploy|
         
     | 
| 
      
 74 
     | 
    
         
            +
                  work_dir = @output.workingDir(app)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  if (force)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    paas.deploy(work_dir, app, deploy, true)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  else
         
     | 
| 
      
 78 
     | 
    
         
            +
                    paas.deploy(work_dir, app, deploy) unless app.isDeployedAt(deploy.manifest_url(app))
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                }
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              def bg_deploy(environment, paas, force=false)
         
     | 
| 
      
 84 
     | 
    
         
            +
                apps = []
         
     | 
| 
      
 85 
     | 
    
         
            +
                eachAppDeployment(environment) { |app, deploy|
         
     | 
| 
      
 86 
     | 
    
         
            +
                  if (force or !app.isDeployedAt(deploy.manifest_url(app)))
         
     | 
| 
      
 87 
     | 
    
         
            +
                    paas.bg_deploy(@output.workingDir(app), app, deploy)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
                }
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              def eachAppDeployment(environment)
         
     | 
| 
      
 93 
     | 
    
         
            +
                selected_deployments = environment.deployments.select{ |d| @deploy_shipcloud.nil? || d.shipcloud == @deploy_shipcloud }
         
     | 
| 
      
 94 
     | 
    
         
            +
                puts "WARNING no deploys selected: #{@deploy_shipcloud}" if selected_deployments.empty?
         
     | 
| 
      
 95 
     | 
    
         
            +
                selected_deployments.each do |d|
         
     | 
| 
      
 96 
     | 
    
         
            +
                  d.app_ids.each do |a|
         
     | 
| 
      
 97 
     | 
    
         
            +
                    app = @apps[a]
         
     | 
| 
      
 98 
     | 
    
         
            +
                    yield app, d unless app.nil?
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
              end
         
     | 
| 
      
 102 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'conan/application'
         
     | 
| 
      
 2 
     | 
    
         
            +
            class RailsZipApp < Application
         
     | 
| 
      
 3 
     | 
    
         
            +
              attr_accessor :sha1, :artifact_repo
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def initialize(id, project_name, artifact_repo, options, url_segment=nil)
         
     | 
| 
      
 6 
     | 
    
         
            +
                super(id, project_name, :rails_zip, options, url_segment)
         
     | 
| 
      
 7 
     | 
    
         
            +
                @sha1 = nil
         
     | 
| 
      
 8 
     | 
    
         
            +
                @artifact_repo = artifact_repo
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
            end
         
     |