bosh-workspace 0.9.6 → 0.9.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9da3815bae98d1612dc8108666ca2a2843d301dd
4
- data.tar.gz: e8592ea8c80c6dcab8c86fa502ed18b8ea390a7f
3
+ metadata.gz: 655a076bbeaf50fdc59837d9c103817bb85dbdf2
4
+ data.tar.gz: dfad167f3135ee92c600d175e465fa0f477cf83b
5
5
  SHA512:
6
- metadata.gz: 0262e9881e357eab8e143a268a8115236b4ae9da9bd3d46d9ca409b0aa75f843dbc1bf7285451e227cd8056f51eea5035c31e3c4a40c52c36cb8f31804393d2a
7
- data.tar.gz: a8b244be56f42052be702bb5f23d9bcc6c6963376517b0d488a1e29e14c41017b504a08c74ac412bd8fee4eedf61c8ae75802b09d38c560d3794f794b59c9d6e
6
+ metadata.gz: c7ab2bc5704fa7b391517397c05d3b222a309acd3977cb6a0bb63b76ab480b03c8520aeea1d5533c52bd37e06327a9f058c62d97de44fa4d0fd0894c072b8524
7
+ data.tar.gz: c28c6c5a73c44e44d9f440554e370d90222f3f6211ea1a662bc777d27cb7568743dde51437b40af844137cd69a13409fc9709e975e703679bd0990c5d5e27e94
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ *~
3
4
  .bundle
4
5
  .config
5
6
  .yardoc
@@ -18,3 +19,5 @@ tmp
18
19
  *.generated_manifests
19
20
  *.DS_Store
20
21
  /spec/assets/manifests-repo/.releases/*
22
+ .idea
23
+
@@ -1 +1 @@
1
- 2.1.4
1
+ 2.2.3
@@ -3,6 +3,8 @@ cache: bundler
3
3
  sudo: false
4
4
  rvm:
5
5
  - 2.0
6
+ - 2.1
7
+ - 2.2
6
8
  before_script:
7
9
  - wget https://github.com/cloudfoundry-incubator/spiff/releases/download/v1.0.7/spiff_linux_amd64.zip -O /tmp/spiff.zip
8
10
  - unzip /tmp/spiff.zip && mkdir bin && mv spiff bin && chmod +x bin/spiff
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gemspec
6
6
  group :development do
7
7
  gem "guard-rspec"
8
8
  gem "rubocop"
9
+ gem "pry"
9
10
  end
10
11
 
11
12
  group :test do
data/Guardfile CHANGED
@@ -1,4 +1,6 @@
1
- guard :rspec, cmd: 'rspec', notification: false do
1
+ # workaround for https://github.com/guard/guard-rspec/issues/348
2
+ rspec_results = File.expand_path('rspec_guard_result')
3
+ guard :rspec, cmd: 'bundle exec rspec --fail-fast', notification: false, results_file: rspec_results do
2
4
  watch(%r{^spec/(.+_spec)\.rb$})
3
5
  watch(%r{^lib/bosh/cli/commands/(.+)\.rb$}) { |m| "spec/commands/#{m[1]}_spec.rb" }
4
6
  watch(%r{^lib/bosh/workspace/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
data/README.md CHANGED
@@ -125,6 +125,12 @@ Example `.credentials.yml` file:
125
125
 
126
126
  ## Install Notes
127
127
 
128
+ ### OSX
129
+ cmake isneeded and libssh2 is optionally (only needed when using cloning over ssh)
130
+ ```
131
+ brew install cmake libssh2
132
+ ```
133
+
128
134
  ### Ubuntu
129
135
  cmake and libcurl4-openssl-dev is needed for rugged install
130
136
 
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_runtime_dependency "semi_semantic", "~> 1.1.0"
26
26
  spec.add_runtime_dependency "membrane", "~> 1.1.0"
27
27
  spec.add_runtime_dependency "hashdiff", "~> 0.2.1"
28
- spec.add_runtime_dependency "rugged", "~> 0.23.0b3"
28
+ spec.add_runtime_dependency "rugged", "~> 0.24.0b11"
29
29
 
30
30
  spec.add_development_dependency "bundler", "~> 1.6"
31
31
  spec.add_development_dependency "rspec", "~> 3.3.0"
@@ -84,7 +84,7 @@ module Bosh::Cli::Command
84
84
  unless stemcell.downloaded?
85
85
  err "Stemcell not available offline: #{stemcell.file_name}" if offline?
86
86
  say "Downloading '#{stemcell.name_version.make_green}'"
87
- stemcell_download(stemcell.file_name)
87
+ stemcell_download(stemcell)
88
88
  end
89
89
  say "Uploading '#{stemcell.name_version.make_green}'"
90
90
  stemcell_upload(stemcell.file)
@@ -56,7 +56,7 @@ module Bosh::Workspace
56
56
  when %i(ssh_key)
57
57
  key_file = temp_key_file(credentials[:private_key])
58
58
  Rugged::Credentials::SshKey.new username: user, privatekey: key_file
59
- when %i(plain_text)
59
+ when %i(plaintext)
60
60
  Rugged::Credentials::UserPassword.new(credentials)
61
61
  end
62
62
  end
@@ -1,12 +1,15 @@
1
+ require 'httpclient'
2
+ require 'cli/download_with_progress'
3
+
1
4
  module Bosh::Workspace
2
5
  module StemcellHelper
3
6
  include ProjectDeploymentHelper
4
7
 
5
- def stemcell_download(stemcell_name)
8
+ def stemcell_download(stemcell)
6
9
  Dir.chdir(stemcells_dir) do
7
- say "Downloading stemcell '#{stemcell_name}'"
10
+ say "Downloading stemcell '#{stemcell.name}' version '#{stemcell.version}'"
8
11
  nl
9
- stemcell_cmd.download_public(stemcell_name)
12
+ download_stemcell_from_bosh_io(stemcell)
10
13
  end
11
14
  end
12
15
 
@@ -36,10 +39,38 @@ module Bosh::Workspace
36
39
  end
37
40
  end
38
41
 
42
+ def download_stemcell_from_bosh_io(stemcell)
43
+
44
+ url = "https://bosh.io/d/stemcells/#{stemcell.name}?v=#{stemcell.version}"
45
+
46
+ response = HTTPClient.new.head(url)
47
+
48
+ if response.status == 302
49
+ location = response.header['location'][0]
50
+ response2 = HTTPClient.new.head(location)
51
+
52
+ if response2.status == 200
53
+ size = response2.header['Content-Length'][0]
54
+ else
55
+ say("HTTP #{response2.status} : #{location}".make_red)
56
+ say(" - redirected from: : #{url}".make_red)
57
+ return
58
+ end
59
+ else
60
+ say("HTTP #{response.status} : #{url} (expecting 302 - redirect)".make_red)
61
+ return
62
+ end
63
+
64
+ download_with_progress = Bosh::Cli::DownloadWithProgress.new(location, size.to_i)
65
+ download_with_progress.perform
66
+ end
67
+
39
68
  private
40
69
 
41
70
  def stemcell_cmd
42
71
  @stemcell_cmd ||= Bosh::Cli::Command::Stemcell.new
43
72
  end
73
+
44
74
  end
75
+
45
76
  end
@@ -1,6 +1,7 @@
1
1
  module Bosh::Workspace
2
2
  class ProjectDeployment
3
3
  include Bosh::Cli::Validation
4
+ include Bosh::Exec
4
5
  attr_writer :director_uuid, :stub
5
6
  attr_reader :file
6
7
 
@@ -35,7 +36,7 @@ module Bosh::Workspace
35
36
 
36
37
  def manifest
37
38
  return @manifest unless @manifest.nil?
38
- @manifest = Psych.load(ERB.new(File.read(file)).result)
39
+ @manifest = YAML.load(ERB.new(IO.read(file)).result)
39
40
  validate_stub! unless stub.empty?
40
41
  @manifest = recursive_merge(@manifest, stub) unless stub.empty?
41
42
  @manifest
@@ -43,8 +44,7 @@ module Bosh::Workspace
43
44
 
44
45
  def stub
45
46
  return @stub unless @stub.nil?
46
- stub_file = File.expand_path(File.join(file_dirname, "../stubs", file_basename))
47
- @stub = File.exist?(stub_file) ? Psych.load(File.read(stub_file)) : {}
47
+ @stub = stub_file ? load_stub : {}
48
48
  end
49
49
 
50
50
  %w[name templates releases stemcells meta domain_name].each do |var|
@@ -55,14 +55,46 @@ module Bosh::Workspace
55
55
 
56
56
  private
57
57
 
58
+ def stubs_dir
59
+ File.expand_path(File.join(file_dirname, "../stubs"))
60
+ end
61
+
62
+ def stub_file
63
+ Dir[File.join(stubs_dir, "#{file_basename('.*')}*")].first
64
+ end
65
+
66
+ def executable_stub?
67
+ File.executable?(stub_file)
68
+ end
69
+
70
+ def load_stub
71
+ begin
72
+ YAML.load(executable_stub? ? execute_stub! : IO.read(stub_file))
73
+ rescue Psych::SyntaxError => e
74
+ say "Error loading stub file for deployment #{file} due to invalid YAML"
75
+ err "error: #{e.message}"
76
+ end
77
+ end
78
+
79
+ def execute_stub!
80
+ sh(stub_file, yield: :on_false) do |result|
81
+ execute_stub_failed!(result.command, result.output) if result.failed?
82
+ end.output
83
+ end
84
+
85
+ def execute_stub_failed!(stub, output)
86
+ say("An error occured while executing stub file: #{stub}")
87
+ err("error: '#{output}'")
88
+ end
89
+
58
90
  def validate_stub!
59
91
  return unless stub.keys.any? { |k| !STUB_WHITELIST.include?(k) }
60
92
  offending_keys = stub.keys - STUB_WHITELIST
61
93
  err "Key: '#{offending_keys.first}' not allowed in stub file"
62
94
  end
63
95
 
64
- def file_basename
65
- File.basename(@file)
96
+ def file_basename(filter = '')
97
+ File.basename(@file, filter)
66
98
  end
67
99
 
68
100
  def file_dirname
@@ -76,11 +76,11 @@ module Bosh::Workspace
76
76
  repo_exists? ? open_repo : init_repo
77
77
  end
78
78
 
79
- def fetch_repo(repo = repo)
79
+ def fetch_repo(_repo = repo)
80
80
  return if offline?
81
- repo.fetch('origin', REFSPEC, credentials: @credentials_callback)
82
- commit = repo.references['refs/remotes/origin/HEAD'].resolve.target_id
83
- update_repo_with_ref(repo, commit)
81
+ _repo.fetch('origin', REFSPEC, credentials: @credentials_callback)
82
+ commit = _repo.references['refs/remotes/origin/HEAD'].resolve.target_id
83
+ update_repo_with_ref(_repo, commit)
84
84
  end
85
85
 
86
86
  def repo_exists?(dir = @repo_dir)
@@ -17,6 +17,7 @@ module Bosh::Workspace
17
17
  return if object.is_a? Integer
18
18
  return if object.is_a? Float
19
19
  return if object == "latest"
20
+ return if object.to_s =~ /^\d+$/
20
21
  return if object.to_s =~ /^\d+(\.\d+){1,2}$/
21
22
  raise Membrane::SchemaValidationError.new(
22
23
  "Should match: latest, version.patch.micropatch, version.patch or version. Given: #{object}")
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Manifests
3
- VERSION = "0.9.6"
3
+ VERSION = "0.9.7"
4
4
  end
5
5
  end
@@ -0,0 +1,4 @@
1
+ name: foobar
2
+ templates:
3
+ - foo/bar.yml
4
+ meta: {}
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ echo 'director_uuid: bar-uuid'
4
+ echo 'name: foobar'
5
+ echo "meta: { 'foo': 'foobar', 'bar': 'foo' }"
@@ -139,7 +139,7 @@ describe Bosh::Cli::Command::Prepare do
139
139
  let(:stemcell_downloaded) { false }
140
140
 
141
141
  it "downloads and uploads the stemcell" do
142
- expect(command).to receive(:stemcell_download).with(stemcell.file_name)
142
+ expect(command).to receive(:stemcell_download).with(stemcell)
143
143
  expect(command).to receive(:stemcell_upload).with(stemcell.file)
144
144
  command.prepare
145
145
  end
@@ -8,7 +8,7 @@ module Bosh::Workspace
8
8
  let(:url) { 'http://foo.com/bar.git' }
9
9
  let(:user) { nil }
10
10
  let(:result) { nil }
11
- let(:allowed_types) { [:plain_text] }
11
+ let(:allowed_types) { [:plaintext] }
12
12
  let(:credentials) do
13
13
  instance_double "Bosh::Workspace::Credentials",
14
14
  :valid? => valid, url_protocols: url_protocols
@@ -38,7 +38,7 @@ module Bosh::Workspace
38
38
 
39
39
  context "with username/password" do
40
40
  let(:result) { { username: user, password: 'barpw' } }
41
- let(:allowed_types) { [:plain_text] }
41
+ let(:allowed_types) { [:plaintext] }
42
42
 
43
43
  it 'returns Rugged user password credentials' do
44
44
  expect(Rugged::Credentials::UserPassword).to receive(:new) do |args|
@@ -23,12 +23,13 @@ describe Bosh::Workspace::StemcellHelper do
23
23
  end
24
24
 
25
25
  describe "#stemcell_download" do
26
- let(:name) { "foo" }
27
- subject { stemcell_helper.stemcell_download(name) }
26
+ let(:stemcell) { instance_double("Bosh::Workspace::Stemcell", :name => "foo", :version => "1") }
27
+
28
+ subject { stemcell_helper.stemcell_download(stemcell) }
28
29
 
29
30
  it "downloads stemcell" do
30
31
  expect(Dir).to receive(:chdir).and_yield
31
- expect(stemcell_cmd).to receive(:download_public).with(name)
32
+ expect(stemcell_helper).to receive(:download_stemcell_from_bosh_io).with(stemcell)
32
33
  subject
33
34
  end
34
35
  end
@@ -1,11 +1,10 @@
1
1
  module Bosh::Workspace
2
2
  describe ProjectDeployment do
3
3
  subject { Bosh::Workspace::ProjectDeployment.new manifest_file }
4
- let(:manifest_content) { ruby_code + manifest.to_yaml }
4
+ let(:manifest_content) { manifest.to_yaml }
5
5
  let(:manifest_file) { get_tmp_file_path(manifest_content, file_name) }
6
6
  let(:file_name) { "foo.yml" }
7
7
  let(:manifest) { :manifest }
8
- let(:ruby_code) { "<% ruby_var=42 %>" }
9
8
 
10
9
  describe ".new" do
11
10
  context "deployment file does not exist" do
@@ -17,13 +16,19 @@ module Bosh::Workspace
17
16
  end
18
17
 
19
18
  describe '#manifest' do
20
- let(:stub_file) { /stubs\/#{file_name}/ }
21
- before do
22
- allow(File).to receive(:exist?).with(manifest_file).and_return(true)
23
- allow(File).to receive(:read).with(manifest_file).and_return(manifest_content)
24
- end
25
-
26
19
  context 'with stub file' do
20
+ let!(:stub_file) do
21
+ path = "../../stubs/#{stub_filename}"
22
+ File.expand_path(path, manifest_file).tap do |file|
23
+ FileUtils.mkdir_p File.dirname(file)
24
+ IO.write(file, stub_content)
25
+ end
26
+ end
27
+
28
+ after { FileUtils.rm(stub_file) }
29
+
30
+ let(:stub_filename) { File.basename(manifest_file) }
31
+
27
32
  let(:manifest) { { 'director_uuid' => 'DIRECTOR_UUID' } }
28
33
  let(:stub_content) do
29
34
  {
@@ -33,11 +38,6 @@ module Bosh::Workspace
33
38
  }.to_yaml
34
39
  end
35
40
 
36
- before do
37
- allow(File).to receive(:exist?).with(stub_file).and_return(true)
38
- allow(File).to receive(:read).with(stub_file).and_return(stub_content)
39
- end
40
-
41
41
  it 'merges stub with manifest' do
42
42
  expect(subject.manifest['director_uuid']).to eq('foo-uuid')
43
43
  end
@@ -51,13 +51,53 @@ module Bosh::Workspace
51
51
  end
52
52
  end
53
53
 
54
- context 'without stub file' do
55
- let(:manifest) { { 'director_uuid' => 'litmus' } }
54
+ context 'with executable stub file' do
55
+ let(:stub_file) { asset_dir("manifests-repo/stubs/foobar.sh") }
56
+ let(:manifest_file) { asset_dir("manifests-repo/deployments/foobar.yml") }
57
+ let(:manifest) do
58
+ {
59
+ 'name' => 'NAME',
60
+ 'director_uuid' => 'DIRECTOR_UUID',
61
+ 'meta' => { 'foo' => 'bar', 'bar' => 'foo' }
62
+ }
63
+ end
56
64
 
57
- before do
58
- allow(File).to receive(:exist?).with(stub_file).and_return(false)
65
+ it 'merges stub output with manifest' do
66
+ expect(subject.manifest['name']).to eq('foobar')
67
+ expect(subject.manifest['director_uuid']).to eq('bar-uuid')
68
+ expect(subject.manifest['meta']).to eq({ 'foo' => 'foobar', 'bar' => 'foo' })
59
69
  end
60
70
 
71
+
72
+ context 'which are invalid' do
73
+ let(:result) { Bosh::Exec::Result.new('foo.sh', 'foo: error:', exit_code) }
74
+
75
+ before do
76
+ expect(subject).to receive(:sh).and_yield(result).and_return(result)
77
+ end
78
+
79
+ context 'non valid yaml returned' do
80
+ let(:exit_code) { 0 }
81
+
82
+ it 'raises an error' do
83
+ expect{ subject.manifest }.to raise_error /mapping values are not allowed/
84
+ end
85
+ end
86
+
87
+ context 'failure during execution' do
88
+ let(:exit_code) { 1 }
89
+
90
+ it 'raises an error' do
91
+ expect{ subject.manifest }.to raise_error /foo: error/
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ context 'without stub file' do
98
+ let(:file_name) { 'bar.yml' }
99
+ let(:manifest) { { 'director_uuid' => 'litmus' } }
100
+
61
101
  it 'reads manifest without errors' do
62
102
  expect(subject.manifest['director_uuid']).to eq('litmus')
63
103
  end
@@ -68,7 +108,7 @@ module Bosh::Workspace
68
108
  context "valid" do
69
109
  it "validates" do
70
110
  allow_any_instance_of(Schemas::ProjectDeployment)
71
- .to receive(:validate).with(manifest)
111
+ .to receive(:validate).with(manifest)
72
112
  expect(subject).to be_valid
73
113
  end
74
114
  end
@@ -76,8 +116,8 @@ module Bosh::Workspace
76
116
  context "invalid" do
77
117
  it "has errors" do
78
118
  allow_any_instance_of(Schemas::ProjectDeployment)
79
- .to receive(:validate).with(manifest)
80
- .and_raise(Membrane::SchemaValidationError.new("foo"))
119
+ .to receive(:validate).with(manifest)
120
+ .and_raise(Membrane::SchemaValidationError.new("foo"))
81
121
  expect(subject).to_not be_valid
82
122
  expect(subject.errors).to include "foo"
83
123
  end
@@ -91,18 +131,18 @@ module Bosh::Workspace
91
131
 
92
132
  describe "attr readers" do
93
133
  let(:manifest) { {
94
- "name" => :name,
95
- "director_uuid" => :director_uuid,
96
- "templates" => :templates,
97
- "releases" => :releases,
98
- "stemcells" => :stemcells,
99
- "meta" => :meta,
100
- "domain_name" => :domain_name,
101
- } }
134
+ "name" => :name,
135
+ "director_uuid" => :director_uuid,
136
+ "templates" => :templates,
137
+ "releases" => :releases,
138
+ "stemcells" => :stemcells,
139
+ "meta" => :meta,
140
+ "domain_name" => :domain_name,
141
+ } }
102
142
 
103
143
  let(:director_uuid) { uuid }
104
144
  %w(name director_uuid templates releases stemcells meta domain_name)
105
- .each do |attr|
145
+ .each do |attr|
106
146
  its(attr.to_sym) { should eq attr.to_sym }
107
147
  end
108
148
  end
@@ -38,6 +38,11 @@ module Bosh::Workspace::Schemas
38
38
  it { expect { subject }.to_not raise_error }
39
39
  end
40
40
 
41
+ context "version string with all digetes without dots" do
42
+ let(:stemcells) { stemcell["version"] = '0000'; [stemcell] }
43
+ it { expect { subject }.to_not raise_error }
44
+ end
45
+
41
46
  context "invalid version" do
42
47
  let(:stemcells) { stemcell["version"] = "foo"; [stemcell] }
43
48
  it { expect { subject }.to raise_error(/version.*should match/i) }
@@ -15,6 +15,8 @@ require "rspec/its"
15
15
  require "tmpdir"
16
16
  require "archive/zip"
17
17
 
18
+ require "pry"
19
+
18
20
  # bosh_cli
19
21
  require "cli"
20
22
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh-workspace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruben Koster
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-23 00:00:00.000000000 Z
11
+ date: 2015-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_cli
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.23.0b3
89
+ version: 0.24.0b11
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.23.0b3
96
+ version: 0.24.0b11
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: bundler
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -231,7 +231,9 @@ files:
231
231
  - spec/assets/manifests-repo/.manifests/foo.yml
232
232
  - spec/assets/manifests-repo/deployments/bar.yml
233
233
  - spec/assets/manifests-repo/deployments/foo.yml
234
+ - spec/assets/manifests-repo/deployments/foobar.yml
234
235
  - spec/assets/manifests-repo/stubs/foo.yml
236
+ - spec/assets/manifests-repo/stubs/foobar.sh
235
237
  - spec/assets/manifests-repo/templates/foo/bar.yml
236
238
  - spec/assets/submodule-boshrelease-repo.zip
237
239
  - spec/assets/supermodule-boshrelease-repo.zip
@@ -286,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
286
288
  version: '0'
287
289
  requirements: []
288
290
  rubyforge_project:
289
- rubygems_version: 2.4.6
291
+ rubygems_version: 2.4.5.1
290
292
  signing_key:
291
293
  specification_version: 4
292
294
  summary: Manage your bosh workspace
@@ -308,7 +310,9 @@ test_files:
308
310
  - spec/assets/manifests-repo/.manifests/foo.yml
309
311
  - spec/assets/manifests-repo/deployments/bar.yml
310
312
  - spec/assets/manifests-repo/deployments/foo.yml
313
+ - spec/assets/manifests-repo/deployments/foobar.yml
311
314
  - spec/assets/manifests-repo/stubs/foo.yml
315
+ - spec/assets/manifests-repo/stubs/foobar.sh
312
316
  - spec/assets/manifests-repo/templates/foo/bar.yml
313
317
  - spec/assets/submodule-boshrelease-repo.zip
314
318
  - spec/assets/supermodule-boshrelease-repo.zip