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,95 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'digest'
|
3
|
+
|
4
|
+
class DefaultArtifactRepository
|
5
|
+
@@artifact_repository_url = 'http://nexus.mtnsatcloud.com/nexus'
|
6
|
+
@@artifact_repository_local_api_url = "#{@@artifact_repository_url}/service/local/artifact/maven"
|
7
|
+
|
8
|
+
def resolveArtifact(group_id, artifact_id, extension, version='LATEST')
|
9
|
+
# we only care about the releases repo, no snapshots please
|
10
|
+
RestClient.get("#{@@artifact_repository_local_api_url}/resolve?r=releases&g=#{group_id}&a=#{artifact_id}&v=#{version}&e=#{extension}")
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def downloadArtifact(output_dir, group_id, artifact_id, extension, version, sha1_hash)
|
15
|
+
if (extension == 'jar')
|
16
|
+
# put jars in a parent directory
|
17
|
+
output_dir = File.join(output_dir, "#{artifact_id}")
|
18
|
+
end
|
19
|
+
url="#{@@artifact_repository_local_api_url}/content?r=releases&g=#{group_id}&a=#{artifact_id}&v=#{version}&e=#{extension}"
|
20
|
+
target_file = File.join(output_dir, "#{artifact_id}.#{extension}")
|
21
|
+
HttpUtil.download(url, target_file, "#{artifact_id}-#{version}.#{extension}", sha1_hash)
|
22
|
+
|
23
|
+
# extract tar balls
|
24
|
+
if (extension == 'tar.gz')
|
25
|
+
dir = "#{output_dir}/#{artifact_id}"
|
26
|
+
FileUtils.rm_rf dir
|
27
|
+
FileUtils.mkdir_p dir
|
28
|
+
`tar -xf #{target_file} -C #{dir}`
|
29
|
+
# TODO fail if tar doesn't work
|
30
|
+
|
31
|
+
# extract deploy artifacts
|
32
|
+
elsif (extension == 'jar')
|
33
|
+
# templates
|
34
|
+
dir = "#{output_dir}/deploy-templates"
|
35
|
+
FileUtils.rm_rf dir
|
36
|
+
FileUtils.mkdir_p dir
|
37
|
+
c = "unzip -j #{target_file} 'META-INF/deploy/templates/*.erb' -d '#{dir}'"
|
38
|
+
system(c) or raise "unzip failed: #{c}"
|
39
|
+
|
40
|
+
# new relic extensions
|
41
|
+
dir = "#{output_dir}/extensions"
|
42
|
+
FileUtils.rm_rf dir
|
43
|
+
FileUtils.mkdir_p dir
|
44
|
+
c = "unzip -j #{target_file} 'META-INF/deploy/extensions/*.yml' -d '#{dir}'"
|
45
|
+
system(c) # extensions are optional, it's ok if this one fails
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def downloadNewRelicAgent(output_dir, nr_version, sha1_hash)
|
50
|
+
url = "#{@@artifact_repository_url}/content/groups/public/com/newrelic/agent/java/newrelic-agent/#{nr_version}/newrelic-agent-#{nr_version}.jar"
|
51
|
+
target_file = File.join(output_dir, "newrelic.jar")
|
52
|
+
HttpUtil.download(url, target_file, "newrelic-agent-#{nr_version}.jar", sha1_hash)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module HttpUtil
|
57
|
+
def self.download(url, target_file, download_file_name, sha1_hash)
|
58
|
+
not_shasum = ->(file) {
|
59
|
+
ret = true
|
60
|
+
if (File.exists?(file))
|
61
|
+
# verify the file
|
62
|
+
found_hash = Digest::SHA1.file(file).hexdigest
|
63
|
+
puts "Found: #{found_hash}, Want: #{sha1_hash}"
|
64
|
+
if (found_hash != sha1_hash)
|
65
|
+
puts "#{file} is not the file we're looking for. It has a SHA1 hash of #{found_hash}, but #{sha1_hash} is expected"
|
66
|
+
ret = true
|
67
|
+
else
|
68
|
+
puts "#{file} matches checksum"
|
69
|
+
ret = false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
ret
|
73
|
+
}
|
74
|
+
|
75
|
+
if (not_shasum.call(target_file))
|
76
|
+
tmp = File.join(Dir.tmpdir(), "nexus-app-manifest")
|
77
|
+
FileUtils.mkdir_p tmp
|
78
|
+
download_file = File.join(tmp, download_file_name)
|
79
|
+
if (not_shasum.call(download_file))
|
80
|
+
# download it
|
81
|
+
puts "Fetching artifact #{download_file_name}"
|
82
|
+
puts " #{url}"
|
83
|
+
puts "..."
|
84
|
+
wget_cmd = "wget -nv \"#{url}\" --content-disposition --no-use-server-timestamps --output-document \"#{download_file}\""
|
85
|
+
puts wget_cmd
|
86
|
+
system( wget_cmd )
|
87
|
+
raise "Failed to download #{download_file_name}" if not_shasum.call(download_file)
|
88
|
+
end
|
89
|
+
# move download to target file
|
90
|
+
puts "cp #{download_file} to #{target_file}"
|
91
|
+
FileUtils.mkdir_p File.dirname(target_file)
|
92
|
+
FileUtils.copy(download_file, target_file)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class Stackato
|
5
|
+
|
6
|
+
class Commands
|
7
|
+
@@executable = "stackato-3.1.1"
|
8
|
+
@@token_file = File.join(Dir.tmpdir(), "token_#{Time.now.to_i}")
|
9
|
+
|
10
|
+
def initialize(target, dry_run=false)
|
11
|
+
@target = target
|
12
|
+
@dry_run = dry_run
|
13
|
+
end
|
14
|
+
|
15
|
+
def shell_cmd(stackato_cmd, args)
|
16
|
+
base_args = "--target #{@target} --token-file #{@@token_file}"
|
17
|
+
|
18
|
+
cmd = "#{@@executable} #{stackato_cmd} #{base_args} #{args}"
|
19
|
+
|
20
|
+
if @dry_run
|
21
|
+
puts "Dry-run, skipping execution of command: #{cmd}"
|
22
|
+
else
|
23
|
+
system(cmd)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def login(username, password, space)
|
28
|
+
shell_cmd("login", "--space #{space} --password '#{password}' #{username}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def push(manifest)
|
32
|
+
shell_cmd("push", "--manifest #{manifest} --no-prompt --reset")
|
33
|
+
end
|
34
|
+
|
35
|
+
def delete(app_name)
|
36
|
+
shell_cmd("delete", "--no-prompt #{app_name}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(paas_user, paas_password, paas_space, dry_run=false)
|
41
|
+
@paas_user = paas_user
|
42
|
+
@paas_password = paas_password
|
43
|
+
@paas_space = paas_space
|
44
|
+
@dry_run = dry_run
|
45
|
+
@paas_manifest = "stackato.yml"
|
46
|
+
end
|
47
|
+
|
48
|
+
def login(paas_target)
|
49
|
+
# login only one time per target, and only one target at a time
|
50
|
+
if (@session != paas_target)
|
51
|
+
@session = paas_target
|
52
|
+
@commands = Commands.new(paas_target, @dry_run)
|
53
|
+
unless @paas_user.nil?
|
54
|
+
@commands.login(@paas_user, @paas_password, @paas_space)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def deploy(work_dir, app, deployment, force=false)
|
60
|
+
puts ''
|
61
|
+
Dir.chdir(work_dir){
|
62
|
+
login(deployment.paas_target)
|
63
|
+
|
64
|
+
paas_app_name = deployment.name(app)
|
65
|
+
yield paas_app_name if block_given?
|
66
|
+
|
67
|
+
# print out the stackato.yml for posterity
|
68
|
+
puts '------------------------------------------------------------------------------'
|
69
|
+
|
70
|
+
File.open(@paas_manifest, "r") do |f|
|
71
|
+
while (line = f.gets)
|
72
|
+
puts "#{line}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
puts '------------------------------------------------------------------------------'
|
76
|
+
puts ''
|
77
|
+
|
78
|
+
if (force)
|
79
|
+
puts "Deleting #{paas_app_name} if it exists. May be force be with you!"
|
80
|
+
@commands.delete(paas_app_name)
|
81
|
+
end
|
82
|
+
|
83
|
+
puts "Pushing #{paas_app_name}"
|
84
|
+
@commands.push(@paas_manifest)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def bg_deploy(work_dir, app, deployment)
|
89
|
+
puts ''
|
90
|
+
Dir.chdir(work_dir){
|
91
|
+
raise RuntimeError.new "Blue/green deployment is not implemented for the stackato v3 client yet"
|
92
|
+
|
93
|
+
# login(deployment.paas_target)
|
94
|
+
|
95
|
+
# push app
|
96
|
+
|
97
|
+
#if app.is_inactive_node_operational?
|
98
|
+
# switch (remap nodes)
|
99
|
+
# clean (delete inactive nodes)
|
100
|
+
#else
|
101
|
+
# raise RuntimeError.new "#{app}'s inactive node is not operational. Skipping switch and clean."
|
102
|
+
#end
|
103
|
+
}
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module Templates
|
5
|
+
|
6
|
+
# Returns the number of files changed/created
|
7
|
+
def self.evaluate(templates_dir, output_dir, context)
|
8
|
+
no_changes = 0
|
9
|
+
FileUtils.mkdir_p File.dirname(output_dir)
|
10
|
+
Dir.glob(File.join(templates_dir, '*.erb')) do |template|
|
11
|
+
target_file = File.join(output_dir, File.basename(template)[0..-5])
|
12
|
+
eruby = Erubis::Eruby.new(File.read(template))
|
13
|
+
if (File.exist? target_file)
|
14
|
+
Tempfile.open(File.basename template) { |t|
|
15
|
+
t.write(eruby.evaluate(context))
|
16
|
+
t.rewind
|
17
|
+
if (FileUtils.identical? t.path, target_file)
|
18
|
+
puts "-- No change from: #{File.basename template} => #{target_file}"
|
19
|
+
else
|
20
|
+
puts ">> Replace file from template: #{File.basename template} => #{target_file}"
|
21
|
+
puts "------------------------------"
|
22
|
+
puts `diff -y -W 120 #{t.path} #{target_file}`
|
23
|
+
puts "------------------------------"
|
24
|
+
FileUtils.cp t.path, target_file
|
25
|
+
no_changes += 1
|
26
|
+
end
|
27
|
+
}
|
28
|
+
else
|
29
|
+
File.open(target_file, 'w') { |f|
|
30
|
+
puts "++ New file from template: #{File.basename template} => #{target_file}"
|
31
|
+
f.write(eruby.evaluate(context))
|
32
|
+
no_changes += 1
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
no_changes
|
37
|
+
end
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: conan_deploy_stackato3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Reardon
|
8
|
+
- Michael Crane
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-09-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: daphne_util
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 0.2.0
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.2.0
|
28
|
+
description: Provision, configure, deploy and never hear da lamantation of da users
|
29
|
+
email: michael.reardon@mtnsat.com
|
30
|
+
executables:
|
31
|
+
- conan-stackato3
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- README.md
|
36
|
+
- bin/conan-stackato3
|
37
|
+
- lib/conan/application.rb
|
38
|
+
- lib/conan/application_helper.rb
|
39
|
+
- lib/conan/deploy.rb
|
40
|
+
- lib/conan/deployment.rb
|
41
|
+
- lib/conan/environment.rb
|
42
|
+
- lib/conan/has_options.rb
|
43
|
+
- lib/conan/jvm_app.rb
|
44
|
+
- lib/conan/manifest.rb
|
45
|
+
- lib/conan/manifest_builder.rb
|
46
|
+
- lib/conan/newrelic.rb
|
47
|
+
- lib/conan/options.rb
|
48
|
+
- lib/conan/output.rb
|
49
|
+
- lib/conan/pipeline.rb
|
50
|
+
- lib/conan/rails_zip_app.rb
|
51
|
+
- lib/conan/repository.rb
|
52
|
+
- lib/conan/stackato.rb
|
53
|
+
- lib/conan/templates.rb
|
54
|
+
- lib/conan/version.rb
|
55
|
+
homepage: http://github.com/MTNSatelliteComm/conan/README.md
|
56
|
+
licenses: []
|
57
|
+
metadata: {}
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.2.2
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Conan da Deployer
|
78
|
+
test_files: []
|