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
|