vara 0.17.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.
@@ -0,0 +1,110 @@
1
+ require 'tmpdir'
2
+ require 'vara/log'
3
+ require 'vara/product_artifact_validator'
4
+
5
+ module Vara
6
+ class ProductArtifactZipper
7
+ include Loggable
8
+
9
+ def initialize(artifact_path, product_contents)
10
+ @artifact_path = artifact_path
11
+ @product_contents = product_contents
12
+ end
13
+
14
+ def zip!
15
+ remove_previous_artifacts
16
+
17
+ in_tmp_dir do
18
+ copy_dirs_and_files
19
+ create_zip!
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :artifact_path, :product_contents
26
+
27
+ def remove_previous_artifacts
28
+ FileUtils.rm(artifact_path) if File.exist?(artifact_path)
29
+ end
30
+
31
+ def in_tmp_dir
32
+ Dir.mktmpdir do |temp_dir|
33
+ FileUtils.cd(temp_dir) do
34
+ yield
35
+ end
36
+ end
37
+ end
38
+
39
+ def copy_dirs_and_files
40
+ product_metadata = ProductMetadata.from_file(product_contents.metadata_path)
41
+
42
+ copy_and_validate_releases(product_metadata)
43
+
44
+ if product_metadata.explicit_stemcell?
45
+ copy_and_validate_stemcell(product_metadata)
46
+ copy_and_validate_compiled_packages(product_metadata)
47
+ end
48
+
49
+ FileUtils.mkdir('content_migrations')
50
+ FileUtils.cp(product_contents.content_migrations_path, 'content_migrations')
51
+
52
+ FileUtils.mkdir('metadata')
53
+ FileUtils.cp(product_contents.metadata_path, 'metadata')
54
+ end
55
+
56
+ def copy_and_validate_releases(product_metadata)
57
+ FileUtils.mkdir('releases')
58
+
59
+ product_contents.release_paths.each do |release_path|
60
+ FileUtils.cp(release_path, 'releases')
61
+ end
62
+
63
+ product_metadata.releases_metadata.each do |release_metadata|
64
+ ProductArtifactValidator.validate_file_checksum(
65
+ release_metadata,
66
+ File.join('releases', release_metadata.basename)
67
+ )
68
+ end
69
+ end
70
+
71
+ def copy_and_validate_stemcell(product_metadata)
72
+ FileUtils.mkdir('stemcells')
73
+ FileUtils.cp(product_contents.stemcell_path, 'stemcells')
74
+
75
+ ProductArtifactValidator.validate_file_checksum(
76
+ product_metadata.stemcell_metadata,
77
+ File.join('stemcells', product_metadata.stemcell_file)
78
+ )
79
+ end
80
+
81
+ def copy_and_validate_compiled_packages(product_metadata)
82
+ return unless product_contents.has_compiled_packages?
83
+
84
+ FileUtils.mkdir('compiled_packages')
85
+ FileUtils.cp(product_contents.compiled_packages_path, 'compiled_packages')
86
+
87
+ ProductArtifactValidator.validate_file_checksum(
88
+ product_metadata.compiled_packages_metadata,
89
+ File.join('compiled_packages', product_metadata.compiled_packages_file)
90
+ )
91
+ end
92
+
93
+ def create_zip!
94
+ log.info("Creating zip file #{artifact_path}")
95
+ # Split into two steps so that it works inside Docker on a mounted volume
96
+ `zip -r -0 local.pivotal .`
97
+ FileUtils.mv('local.pivotal', artifact_path)
98
+ log.info('Finished creating zip file')
99
+ end
100
+ end
101
+ end
102
+
103
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
104
+ # All rights reserved.
105
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
106
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
107
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
108
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
109
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
110
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,64 @@
1
+ require 'vara/product_metadata'
2
+
3
+ module Vara
4
+ class ProductContents
5
+ # @param metadata_path [String] The path on disk to the metadata YAML file
6
+ # @return [Vara::ProductContents]
7
+ def self.from_metadata_path(metadata_path)
8
+ new(metadata_path, ProductMetadata.from_file(metadata_path))
9
+ end
10
+
11
+ attr_reader :metadata_path
12
+
13
+ # @param metadata_path [String] The path on disk to the metadata YAML file
14
+ # @param product_metadata [Vara::ProductMetadata] The Product Metadata as represented in the metadata_path file
15
+ def initialize(metadata_path, product_metadata)
16
+ @metadata_path = File.expand_path(metadata_path).freeze
17
+ @product_metadata = product_metadata
18
+ end
19
+
20
+ # @return [String] The path to the content migration file on disk
21
+ def content_migrations_path
22
+ paths = Dir.glob(File.expand_path(File.join(root_path, 'content_migrations', '*.yml')))
23
+ fail "Exactly one content_migrations file is required in #{root_path}/content_migrations" if paths.size != 1
24
+ paths.first
25
+ end
26
+
27
+ # @return [<String>] The paths to the release tarballs on disk
28
+ def release_paths
29
+ product_metadata.releases_metadata.map { |release_metadata| File.join(root_path, 'releases', release_metadata.basename) }
30
+ end
31
+
32
+ # @return [String] The path to the stemcell file on disk
33
+ def stemcell_path
34
+ File.join(root_path, 'stemcells', product_metadata.stemcell_file)
35
+ end
36
+
37
+ # @return [String] The path to the compiled packages file on disk
38
+ def compiled_packages_path
39
+ File.join(root_path, 'compiled_packages', product_metadata.compiled_packages_file)
40
+ end
41
+
42
+ # @return [Boolean] Whether the product metadata has a compiled packages field
43
+ def has_compiled_packages?
44
+ product_metadata.has_compiled_packages?
45
+ end
46
+
47
+ private
48
+
49
+ def root_path
50
+ File.expand_path(File.join(metadata_path, '..', '..'))
51
+ end
52
+
53
+ attr_reader :product_metadata
54
+ end
55
+ end
56
+
57
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
58
+ # All rights reserved.
59
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
60
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
61
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
62
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
63
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
64
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,113 @@
1
+ require 'yaml'
2
+ require 'vara/metadata/stemcell'
3
+ require 'vara/metadata/release'
4
+ require 'vara/metadata/compiled_packages'
5
+
6
+ module Vara
7
+ # "Struct" representing the information in metadata/<product_name>.yml
8
+ class ProductMetadata
9
+ # Build a ProductMetadata from a metadata.yml on disk
10
+ # @param metadata_path Path to the product metadata file on disk
11
+ # @return [Vara::ProductMetadata]
12
+ def self.from_file(metadata_path)
13
+ new(YAML.load_file(metadata_path))
14
+ end
15
+
16
+ # @param hash [Hash] the hash representing the product metadata
17
+ def initialize(hash)
18
+ @hash = hash
19
+ end
20
+
21
+ def explicit_stemcell?
22
+ hash.key? 'stemcell'
23
+ end
24
+
25
+ def stemcell_criteria
26
+ return nil if explicit_stemcell?
27
+ hash.fetch('stemcell_criteria')
28
+ end
29
+
30
+ def stemcell_criteria?
31
+ hash.key? 'stemcell_criteria'
32
+ end
33
+
34
+ # @return [Vara::Metadata::Stemcell] the stemcell metadata contained in this ProductMetadata
35
+ def stemcell_metadata
36
+ stemcell = hash.fetch('stemcell')
37
+ Metadata::Stemcell.new(
38
+ name: stemcell.fetch('name'),
39
+ version: stemcell.fetch('version'),
40
+ file: stemcell.fetch('file'),
41
+ md5: stemcell.fetch('md5', nil),
42
+ sha1: stemcell.fetch('sha1', nil)
43
+ )
44
+ end
45
+
46
+ # @return [<Vara::Metadata::Release>] the releases metadata contained in this ProductMetadata
47
+ def releases_metadata
48
+ releases = hash.fetch('releases')
49
+ releases.map { |release| release_metadata(release) }
50
+ end
51
+
52
+ # @raise [KeyNotFoundError] if this ProductMetadata does not contain compiled packages
53
+ # @return [Vara::Metadata::CompiledPackages] the compiled packages metadata contained in this ProductMetadata
54
+ def compiled_packages_metadata
55
+ c = hash.fetch('compiled_package')
56
+ Metadata::CompiledPackages.new(
57
+ c.fetch('name'), c.fetch('version'), c.fetch('file'), c.fetch('md5'), c.fetch('url', nil)
58
+ )
59
+ end
60
+
61
+ # @return [String] the filename of the stemcell
62
+ def stemcell_file
63
+ stemcell_metadata.basename
64
+ end
65
+
66
+ # @return [String] the name of the product
67
+ def name
68
+ hash.fetch('name')
69
+ end
70
+
71
+ # @return [String] the version of the product
72
+ def product_version
73
+ hash.fetch('product_version')
74
+ end
75
+
76
+ # @return [String] the filename of the compiled packages
77
+ def compiled_packages_file
78
+ compiled_packages_metadata.basename
79
+ end
80
+
81
+ # @return [Boolean] whether the compiled packages field is present
82
+ def has_compiled_packages?
83
+ hash.key?('compiled_package')
84
+ end
85
+
86
+ private
87
+
88
+ attr_reader :hash
89
+
90
+ # @return [Vara::Metadata::Release]
91
+ def release_metadata(release_hash)
92
+ release = release_hash
93
+ Metadata::Release.new(
94
+ name: release.fetch('name'),
95
+ version: release.fetch('version'),
96
+ file: release.fetch('file'),
97
+ md5: release.fetch('md5', nil),
98
+ sha1: release.fetch('sha1', nil),
99
+ url: release.fetch('url', nil),
100
+ aws: release.fetch('aws', nil)
101
+ )
102
+ end
103
+ end
104
+ end
105
+
106
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
107
+ # All rights reserved.
108
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
109
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
110
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
111
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
112
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
113
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,98 @@
1
+ require 'yaml'
2
+ require 'vara/log'
3
+
4
+ module Vara
5
+ class ProductMetadataProcessor
6
+ include Vara::Loggable
7
+
8
+ # @param product_dir [String] path to product directory root
9
+ # @param versioner [Vara::PrereleaseVersioner,Vara::StaticVersioner]
10
+ def initialize(product_dir, versioner, external_release_paths: [])
11
+ @product_dir = product_dir
12
+ @versioner = versioner
13
+ @external_release_paths = external_release_paths
14
+ end
15
+
16
+ # Composes metadata_parts/binaries.yml and metadata_parts/handcraft.yml into the properly named product metadata
17
+ # file under metadata/, expanding placeholders as necessary
18
+ # @return [String] The path to the generated metadata file
19
+ def process
20
+ metadata = merged_metadata
21
+
22
+ external_release_paths.each do |external_release_path|
23
+ update_release(external_release_path, metadata)
24
+ end
25
+
26
+ processed = versioner.update_metadata(metadata)
27
+ save_processed_metadata(processed)
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :product_dir, :versioner, :external_release_paths
33
+
34
+ ALLOWED_RELEASE_KEYS = %w(file name url md5 version)
35
+
36
+ def merged_metadata
37
+ binaries_path = File.join(product_dir, 'metadata_parts', 'binaries.yml')
38
+ binaries = YAML.load_file(binaries_path)
39
+ log.info("Composing metadata: loaded #{binaries_path}")
40
+
41
+ handcraft_path = File.join(product_dir, 'metadata_parts', 'handcraft.yml')
42
+ handcraft = YAML.load_file(handcraft_path)
43
+ log.info("Composing metadata: loaded #{handcraft_path}")
44
+
45
+ binaries.merge(handcraft)
46
+ end
47
+
48
+ def update_release(external_release_path, metadata)
49
+ log.info("Updating metadata: using #{File.expand_path(external_release_path)}")
50
+
51
+ external_releases = YAML.load_file(external_release_path)
52
+
53
+ external_releases.each do |release|
54
+ external_release = validate_release(release, external_release_path)
55
+
56
+ replace = metadata['releases'].find_index do |r|
57
+ r['name'] == external_release['name']
58
+ end
59
+
60
+ fail "Specified release #{external_release['name']} does not exist in binaries.yml" unless replace
61
+
62
+ metadata['releases'][replace] = external_release
63
+ end
64
+ end
65
+
66
+ def validate_release(external_release, external_release_path)
67
+ missing_keys = ALLOWED_RELEASE_KEYS - external_release.keys.to_a
68
+ fail "Specified release #{File.basename(external_release_path)} is missing keywords: #{missing_keys}" unless missing_keys.empty?
69
+ extra_keys = external_release.keys.to_a - ALLOWED_RELEASE_KEYS
70
+ fail "Specified release #{File.basename(external_release_path)} has extra keywords: #{extra_keys}" unless extra_keys.empty?
71
+ external_release
72
+ end
73
+
74
+ def save_processed_metadata(processed_metadata_hash)
75
+ product_name = processed_metadata_hash.fetch('name').tr('-', '_')
76
+ metadata_dir = File.join(product_dir, 'metadata')
77
+
78
+ FileUtils.mkdir_p(metadata_dir)
79
+
80
+ out_path = File.join(metadata_dir, "#{product_name}.yml")
81
+
82
+ File.open(out_path, 'w') do |out|
83
+ YAML.dump(processed_metadata_hash, out)
84
+ end
85
+
86
+ out_path
87
+ end
88
+ end
89
+ end
90
+
91
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
92
+ # All rights reserved.
93
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
94
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
95
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
96
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
97
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
98
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,69 @@
1
+ require 'vara/product_metadata'
2
+ require 'vara/tarball'
3
+
4
+ module Vara
5
+ class ProductResourceDownloader
6
+ def self.build(product_metadata_path)
7
+ product_metadata = Vara::ProductMetadata.from_file(product_metadata_path)
8
+ product_basedir = File.expand_path(File.join(File.dirname(product_metadata_path), '..'))
9
+ new(product_metadata, product_basedir)
10
+ end
11
+
12
+ attr_reader :product_basedir, :product_metadata
13
+
14
+ def initialize(product_metadata, product_basedir)
15
+ @product_basedir = product_basedir
16
+ @product_metadata = product_metadata
17
+ end
18
+
19
+ def download
20
+ if product_metadata.explicit_stemcell? && product_metadata.stemcell_criteria?
21
+ fail 'binaries.yml includes both stemcell and stemcell criteria keys'
22
+ end
23
+
24
+ if product_metadata.explicit_stemcell?
25
+ download_stemcell
26
+ download_compiled_packages
27
+ end
28
+
29
+ download_releases
30
+ end
31
+
32
+ private
33
+
34
+ def download_stemcell
35
+ stemcell_metadata = product_metadata.stemcell_metadata
36
+ stemcell_directory = File.join(product_basedir, 'stemcells')
37
+ stemcell = Vara::Tarball.new(stemcell_metadata, stemcell_directory)
38
+ stemcell.sync_local_copy
39
+ end
40
+
41
+ def download_releases
42
+ releases_metadata = product_metadata.releases_metadata
43
+
44
+ releases_metadata.each do |release_metadata|
45
+ release_directory = File.join(product_basedir, 'releases')
46
+ release = Vara::Tarball.new(release_metadata, release_directory)
47
+ release.sync_local_copy
48
+ end
49
+ end
50
+
51
+ def download_compiled_packages
52
+ return unless product_metadata.has_compiled_packages?
53
+
54
+ compiled_packages_metadata = product_metadata.compiled_packages_metadata
55
+ compiled_packages_dir = File.join(product_basedir, 'compiled_packages')
56
+ compiled_package = Vara::Tarball.new(compiled_packages_metadata, compiled_packages_dir)
57
+ compiled_package.sync_local_copy
58
+ end
59
+ end
60
+ end
61
+
62
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
63
+ # All rights reserved.
64
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
65
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
66
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
67
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
68
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
69
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.