Skip to content

Commit 6caebd3

Browse files
committed
Validate checksums when fetching cached files for app packaging
* This also deletes any resources with bad/mismatched checksums
1 parent d84cd86 commit 6caebd3

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

errors/v2.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,11 @@
613613
http_code: 502
614614
message: "Deletion of app %s failed because one or more associated resources could not be deleted.\n\n%s"
615615

616+
150010:
617+
name: ResourceChecksumMismatch
618+
http_code: 500
619+
message: "One or more cached resources did not match the given checksum. They have been deleted; please retry package upload."
620+
616621
160001:
617622
name: AppBitsUploadInvalid
618623
http_code: 400

lib/cloud_controller/packager/shared_bits_packer.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,19 @@ def append_matched_resources(app_packager, cached_files_fingerprints, root_path)
4242
cached_resources_dir = File.join(root_path, 'cached_resources_dir')
4343

4444
FileUtils.mkdir(cached_resources_dir)
45+
checksum_mismatch = false
4546
matched_resources.each do |local_destination, file_sha, mode|
47+
file_path = File.join(cached_resources_dir, local_destination)
4648
global_app_bits_cache.download_from_blobstore(file_sha, File.join(cached_resources_dir, local_destination), mode:)
49+
50+
if Digester.new.digest_path(file_path) != file_sha
51+
checksum_mismatch = true
52+
global_app_bits_cache.delete(file_sha)
53+
end
4754
end
55+
56+
raise CloudController::Errors::ApiError.new_from_details('ResourceChecksumMismatch') if checksum_mismatch
57+
4858
app_packager.append_dir_contents(cached_resources_dir)
4959
end
5060

spec/unit/lib/cloud_controller/packager/local_bits_packer_spec.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module CloudController::Packager
2626
)
2727
end
2828

29-
let(:fingerprints) do
29+
let(:corrupted_fingerprints) do
3030
path = File.join(local_tmp_dir, 'content')
3131
sha = 'some_fake_sha'
3232
File.write(path, 'content')
@@ -35,6 +35,15 @@ module CloudController::Packager
3535
[{ 'fn' => 'path/to/content.txt', 'size' => 123, 'sha1' => sha }]
3636
end
3737

38+
let(:fingerprints) do
39+
path = File.join(local_tmp_dir, 'content')
40+
File.write(path, 'content')
41+
sha = Digester.new.digest_path(path)
42+
global_app_bits_cache.cp_to_blobstore(path, sha)
43+
44+
[{ 'fn' => 'path/to/content.txt', 'size' => 123, 'sha1' => sha }]
45+
end
46+
3847
before do
3948
TestConfig.override(directories: { tmpdir: local_tmp_dir })
4049

@@ -136,6 +145,18 @@ module CloudController::Packager
136145
expect(package_blobstore.exists?(blobstore_key)).to be true
137146
end
138147
end
148+
149+
context 'and there are corrupted cached files' do
150+
let(:cached_files_fingerprints) { corrupted_fingerprints }
151+
152+
it 'deletes the offending files from the blobstore and errors with a ChecksumMismatch error' do
153+
expect(global_app_bits_cache).to receive(:delete).with('some_fake_sha')
154+
expect do
155+
packer.send_package_to_blobstore(blobstore_key, uploaded_files_path, cached_files_fingerprints)
156+
end.
157+
to raise_error(CloudController::Errors::ApiError, /One or more cached resources/)
158+
end
159+
end
139160
end
140161

141162
context 'when the zip file is invalid' do

0 commit comments

Comments
 (0)