bosh-director-core 1.1868.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/bosh/director/core/tar_gzipper.rb +41 -0
- data/lib/bosh/director/core/templates/compressed_rendered_job_templates.rb +31 -0
- data/lib/bosh/director/core/templates/job_instance_renderer.rb +31 -0
- data/lib/bosh/director/core/templates/job_template_loader.rb +56 -0
- data/lib/bosh/director/core/templates/job_template_renderer.rb +53 -0
- data/lib/bosh/director/core/templates/rendered_file_template.rb +5 -0
- data/lib/bosh/director/core/templates/rendered_job_instance.rb +50 -0
- data/lib/bosh/director/core/templates/rendered_job_template.rb +23 -0
- data/lib/bosh/director/core/templates/rendered_templates_archive.rb +16 -0
- data/lib/bosh/director/core/templates/rendered_templates_writer.rb +25 -0
- data/lib/bosh/director/core/templates/src_file_template.rb +5 -0
- data/lib/bosh/director/core/templates.rb +6 -0
- data/lib/bosh/director/core/version.rb +7 -0
- data/lib/bosh/director/core.rb +6 -0
- metadata +128 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module Bosh::Director::Core
|
5
|
+
class TarGzipper
|
6
|
+
# @param [String] base_dir the directory from which the tar command is run
|
7
|
+
# @param [String, Array] sources the relative paths to include
|
8
|
+
# @param [String] dest the destination filename for the tgz output
|
9
|
+
# @param [Hash] options the options for compress
|
10
|
+
# @option options [Boolean] :copy_first copy the source to a temp dir before archiving
|
11
|
+
def compress(base_dir, sources, dest, options = {})
|
12
|
+
sources = [*sources]
|
13
|
+
sources.each do |source|
|
14
|
+
if source.include?(File::SEPARATOR)
|
15
|
+
raise "Sources must have a path depth of 1 and contain no '#{File::SEPARATOR}'"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
base_dir_path = Pathname.new(base_dir)
|
20
|
+
raise "The base directory #{base_dir} could not be found." unless base_dir_path.exist?
|
21
|
+
raise "The base directory #{base_dir} is not an absolute path." unless base_dir_path.absolute?
|
22
|
+
|
23
|
+
if options[:copy_first]
|
24
|
+
Dir.mktmpdir do |tmpdir|
|
25
|
+
FileUtils.cp_r(sources.map { |s| File.join(base_dir, s) }, "#{tmpdir}/")
|
26
|
+
tar(tmpdir, dest, sources)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
tar(base_dir, dest, sources)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def tar(base_dir, dest, sources)
|
36
|
+
out, err, status = Open3.capture3('tar', '-C', base_dir, '-czf', dest, *sources)
|
37
|
+
raise("tar exited #{status.exitstatus}, output: '#{out}', error: '#{err}'") unless status.success?
|
38
|
+
out
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'digest/sha1'
|
3
|
+
require 'bosh/director/core/templates'
|
4
|
+
require 'bosh/director/core/tar_gzipper'
|
5
|
+
require 'bosh/director/core/templates/rendered_templates_writer'
|
6
|
+
|
7
|
+
module Bosh::Director::Core::Templates
|
8
|
+
class CompressedRenderedJobTemplates
|
9
|
+
def initialize(path)
|
10
|
+
@path = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def write(rendered_templates)
|
14
|
+
Dir.mktmpdir do |dir|
|
15
|
+
writer = RenderedTemplatesWriter.new
|
16
|
+
writer.write(rendered_templates, dir)
|
17
|
+
|
18
|
+
tar_gzipper = Bosh::Director::Core::TarGzipper.new
|
19
|
+
tar_gzipper.compress(dir, %w(.), @path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def contents
|
24
|
+
File.open(@path, 'r')
|
25
|
+
end
|
26
|
+
|
27
|
+
def sha1
|
28
|
+
Digest::SHA1.file(@path).hexdigest
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'bosh/director/core/templates'
|
2
|
+
require 'bosh/director/core/templates/rendered_job_instance'
|
3
|
+
|
4
|
+
module Bosh::Director::Core::Templates
|
5
|
+
class JobInstanceRenderer
|
6
|
+
def initialize(job, job_template_loader)
|
7
|
+
@job = job
|
8
|
+
@job_template_loader = job_template_loader
|
9
|
+
end
|
10
|
+
|
11
|
+
def render(instance)
|
12
|
+
rendered_templates = job.templates.map do |template|
|
13
|
+
job_template_renderer = job_template_renderers[template.name]
|
14
|
+
job_template_renderer.render(job.name, instance)
|
15
|
+
end
|
16
|
+
|
17
|
+
RenderedJobInstance.new(rendered_templates)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def job_template_renderers
|
23
|
+
@job_template_renderers ||= job.templates.reduce({}) do |hash, template|
|
24
|
+
hash[template.name] = job_template_loader.process(template)
|
25
|
+
hash
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :job_template_loader, :job
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'bosh/director/core/templates'
|
2
|
+
require 'bosh/director/core/templates/job_template_renderer'
|
3
|
+
require 'bosh/director/core/templates/src_file_template'
|
4
|
+
|
5
|
+
module Bosh::Director::Core::Templates
|
6
|
+
class JobTemplateLoader
|
7
|
+
def initialize(logger)
|
8
|
+
@logger = logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def process(job_template)
|
12
|
+
template_dir = extract_template(job_template)
|
13
|
+
manifest = Psych.load_file(File.join(template_dir, 'job.MF'))
|
14
|
+
|
15
|
+
monit_template = erb(File.join(template_dir, 'monit'))
|
16
|
+
monit_template.filename = File.join(job_template.name, 'monit')
|
17
|
+
|
18
|
+
templates = []
|
19
|
+
|
20
|
+
manifest.fetch('templates', {}).each_pair do |src_name, dest_name|
|
21
|
+
erb_file = erb(File.join(template_dir, 'templates', src_name))
|
22
|
+
erb_file.filename = File.join(job_template.name, src_name)
|
23
|
+
templates << SrcFileTemplate.new(src_name, dest_name, erb_file)
|
24
|
+
end
|
25
|
+
|
26
|
+
JobTemplateRenderer.new(job_template.name, monit_template, templates, logger)
|
27
|
+
ensure
|
28
|
+
FileUtils.rm_rf(template_dir) if template_dir
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :logger
|
34
|
+
|
35
|
+
def extract_template(job_template)
|
36
|
+
temp_path = job_template.download_blob
|
37
|
+
template_dir = Dir.mktmpdir('template_dir')
|
38
|
+
|
39
|
+
output = `tar -C #{template_dir} -xzf #{temp_path} 2>&1`
|
40
|
+
if $?.exitstatus != 0
|
41
|
+
raise JobTemplateUnpackFailed,
|
42
|
+
"Cannot unpack `#{job_template.name}' job template, " +
|
43
|
+
"tar returned #{$?.exitstatus}, " +
|
44
|
+
"tar output: #{output}"
|
45
|
+
end
|
46
|
+
|
47
|
+
template_dir
|
48
|
+
ensure
|
49
|
+
FileUtils.rm_f(temp_path) if temp_path
|
50
|
+
end
|
51
|
+
|
52
|
+
def erb(path)
|
53
|
+
ERB.new(File.read(path))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'bosh/director/core/templates'
|
2
|
+
require 'bosh/director/core/templates/rendered_job_template'
|
3
|
+
require 'bosh/director/core/templates/rendered_file_template'
|
4
|
+
require 'common/properties'
|
5
|
+
|
6
|
+
module Bosh::Director::Core::Templates
|
7
|
+
class JobTemplateRenderer
|
8
|
+
|
9
|
+
attr_reader :monit_template, :templates
|
10
|
+
|
11
|
+
def initialize(name, monit_template, templates, logger)
|
12
|
+
@name = name
|
13
|
+
@monit_template = monit_template
|
14
|
+
@templates = templates
|
15
|
+
@logger = logger
|
16
|
+
end
|
17
|
+
|
18
|
+
def render(job_name, instance)
|
19
|
+
template_context = Bosh::Common::TemplateEvaluationContext.new(instance.spec)
|
20
|
+
|
21
|
+
monit = render_erb(job_name, monit_template, template_context, instance.index)
|
22
|
+
|
23
|
+
rendered_templates = templates.map do |template_file|
|
24
|
+
file_contents = render_erb(job_name, template_file.erb_file, template_context, instance.index)
|
25
|
+
RenderedFileTemplate.new(template_file.src_name, template_file.dest_name, file_contents)
|
26
|
+
end
|
27
|
+
|
28
|
+
RenderedJobTemplate.new(name, monit, rendered_templates)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :name, :logger
|
34
|
+
|
35
|
+
def render_erb(job_name, template, template_context, index)
|
36
|
+
template.result(template_context.get_binding)
|
37
|
+
# rubocop:disable RescueException
|
38
|
+
rescue Exception => e
|
39
|
+
logger.debug(e.inspect)
|
40
|
+
job_desc = "#{job_name}/#{index}"
|
41
|
+
line_index = e.backtrace.index { |l| l.include?(template.filename) }
|
42
|
+
line = line_index ? e.backtrace[line_index] : '(unknown):(unknown)'
|
43
|
+
template_name, line = line.split(':')
|
44
|
+
|
45
|
+
message = "Error filling in template `#{File.basename(template_name)}' " +
|
46
|
+
"for `#{job_desc}' (line #{line}: #{e})"
|
47
|
+
|
48
|
+
logger.debug("#{message}\n#{e.backtrace.join("\n")}")
|
49
|
+
raise message
|
50
|
+
end
|
51
|
+
# rubocop:enable RescueException
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'bosh/director/core/templates'
|
2
|
+
require 'bosh/director/core/templates/rendered_templates_archive'
|
3
|
+
require 'bosh/director/core/templates/compressed_rendered_job_templates'
|
4
|
+
require 'digest/sha1'
|
5
|
+
require 'tempfile'
|
6
|
+
|
7
|
+
module Bosh::Director::Core::Templates
|
8
|
+
class RenderedJobInstance
|
9
|
+
def initialize(job_templates)
|
10
|
+
@job_templates = job_templates
|
11
|
+
end
|
12
|
+
|
13
|
+
def configuration_hash
|
14
|
+
instance_digest = Digest::SHA1.new
|
15
|
+
job_templates.sort { |x, y| x.name <=> y.name }.each do |rendered_job_template|
|
16
|
+
bound_templates = ''
|
17
|
+
bound_templates << rendered_job_template.monit
|
18
|
+
|
19
|
+
rendered_job_template.templates.sort { |x, y| x.src_name <=> y.src_name }.each do |template_file|
|
20
|
+
bound_templates << template_file.contents
|
21
|
+
instance_digest << bound_templates
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
instance_digest.hexdigest
|
26
|
+
end
|
27
|
+
|
28
|
+
def template_hashes
|
29
|
+
job_templates.reduce({}) do |h, rendered_job_template|
|
30
|
+
h.merge(rendered_job_template.name => rendered_job_template.template_hash)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def persist(blobstore)
|
35
|
+
file = Tempfile.new('compressed-rendered-job-templates')
|
36
|
+
|
37
|
+
compressed_archive = CompressedRenderedJobTemplates.new(file.path)
|
38
|
+
compressed_archive.write(job_templates)
|
39
|
+
|
40
|
+
blobstore_id = blobstore.create(compressed_archive.contents)
|
41
|
+
RenderedTemplatesArchive.new(blobstore_id, compressed_archive.sha1)
|
42
|
+
ensure
|
43
|
+
file.close!
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :job_templates
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'bosh/director/core/templates'
|
2
|
+
|
3
|
+
module Bosh::Director::Core::Templates
|
4
|
+
class RenderedJobTemplate
|
5
|
+
attr_reader :name, :monit, :templates
|
6
|
+
|
7
|
+
def initialize(name, monit, templates)
|
8
|
+
@name = name
|
9
|
+
@monit = monit
|
10
|
+
@templates = templates
|
11
|
+
end
|
12
|
+
|
13
|
+
def template_hash
|
14
|
+
template_digest = Digest::SHA1.new
|
15
|
+
template_digest << monit
|
16
|
+
templates.sort { |x, y| x.src_name <=> y.src_name }.each do |template_file|
|
17
|
+
template_digest << template_file.contents
|
18
|
+
end
|
19
|
+
|
20
|
+
template_digest.hexdigest
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'bosh/director/core/templates'
|
2
|
+
|
3
|
+
module Bosh::Director::Core::Templates
|
4
|
+
class RenderedTemplatesArchive
|
5
|
+
attr_reader :blobstore_id, :sha1
|
6
|
+
|
7
|
+
def initialize(blobstore_id, sha1)
|
8
|
+
@blobstore_id = blobstore_id
|
9
|
+
@sha1 = sha1
|
10
|
+
end
|
11
|
+
|
12
|
+
def spec
|
13
|
+
{ 'blobstore_id' => @blobstore_id, 'sha1' => @sha1 }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'bosh/director/core/templates'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Bosh::Director::Core::Templates
|
5
|
+
class RenderedTemplatesWriter
|
6
|
+
def write(rendered_templates, output_dir)
|
7
|
+
rendered_templates.each do |job_template|
|
8
|
+
job_template_dir = File.join(output_dir, job_template.name)
|
9
|
+
Dir.mkdir(job_template_dir)
|
10
|
+
|
11
|
+
File.open(File.join(job_template_dir, 'monit'), 'w') do |f|
|
12
|
+
f.write(job_template.monit)
|
13
|
+
end
|
14
|
+
|
15
|
+
job_template.templates.each do |file_template|
|
16
|
+
file_template_dest = File.join(job_template_dir, file_template.dest_name)
|
17
|
+
FileUtils.mkdir_p(File.dirname(file_template_dest))
|
18
|
+
File.open(file_template_dest, 'w') do |f|
|
19
|
+
f.write(file_template.contents)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bosh-director-core
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1868.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pivotal
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-01-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bosh_common
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.1868.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.1868.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: fakefs
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Bosh::Director::Core provides common Director code for Director and Microbosh
|
79
|
+
Deployer
|
80
|
+
email: support@cloudfoundry.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- lib/bosh/director/core.rb
|
86
|
+
- lib/bosh/director/core/tar_gzipper.rb
|
87
|
+
- lib/bosh/director/core/templates.rb
|
88
|
+
- lib/bosh/director/core/templates/compressed_rendered_job_templates.rb
|
89
|
+
- lib/bosh/director/core/templates/job_instance_renderer.rb
|
90
|
+
- lib/bosh/director/core/templates/job_template_loader.rb
|
91
|
+
- lib/bosh/director/core/templates/job_template_renderer.rb
|
92
|
+
- lib/bosh/director/core/templates/rendered_file_template.rb
|
93
|
+
- lib/bosh/director/core/templates/rendered_job_instance.rb
|
94
|
+
- lib/bosh/director/core/templates/rendered_job_template.rb
|
95
|
+
- lib/bosh/director/core/templates/rendered_templates_archive.rb
|
96
|
+
- lib/bosh/director/core/templates/rendered_templates_writer.rb
|
97
|
+
- lib/bosh/director/core/templates/src_file_template.rb
|
98
|
+
- lib/bosh/director/core/version.rb
|
99
|
+
homepage: https://github.com/cloudfoundry/bosh
|
100
|
+
licenses:
|
101
|
+
- Apache 2.0
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 1.9.3
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
hash: -2612646582658106641
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 1.8.23
|
124
|
+
signing_key:
|
125
|
+
specification_version: 3
|
126
|
+
summary: Bosh::Director::Core provides common Director code for Director and Microbosh
|
127
|
+
Deployer
|
128
|
+
test_files: []
|