|
1 | 1 | require 'cloud_controller/blobstore/fingerprints_collection'
|
2 | 2 | require 'cloud_controller/app_packager'
|
3 |
| -require 'cloud_controller/packager/shared_bits_packer' |
| 3 | +require 'shellwords' |
4 | 4 |
|
5 | 5 | module CloudController
|
6 | 6 | module Packager
|
7 | 7 | class ConflictError < StandardError
|
8 | 8 | end
|
9 | 9 |
|
10 | 10 | class LocalBitsPacker
|
11 |
| - include Packager::SharedBitsPacker |
12 | 11 |
|
13 | 12 | def send_package_to_blobstore(blobstore_key, uploaded_package_zip, cached_files_fingerprints)
|
14 | 13 | tmp_dir = VCAP::CloudController::Config.config.get(:directories, :tmpdir)
|
@@ -39,6 +38,84 @@ def send_package_to_blobstore(blobstore_key, uploaded_package_zip, cached_files_
|
39 | 38 | def package_blobstore
|
40 | 39 | CloudController::DependencyLocator.instance.package_blobstore
|
41 | 40 | end
|
| 41 | + |
| 42 | + def package_zip_exists?(package_zip) |
| 43 | + package_zip && File.exist?(package_zip) |
| 44 | + end |
| 45 | + |
| 46 | + def validate_size!(app_packager) |
| 47 | + return unless max_package_size |
| 48 | + |
| 49 | + return unless app_packager.size > max_package_size |
| 50 | + |
| 51 | + raise CloudController::Errors::ApiError.new_from_details('AppPackageInvalid', "Package may not be larger than #{max_package_size} bytes") |
| 52 | + end |
| 53 | + |
| 54 | + def copy_uploaded_package(uploaded_package_zip, app_packager) |
| 55 | + FileUtils.chmod('u+w', uploaded_package_zip) |
| 56 | + FileUtils.cp(uploaded_package_zip, app_packager.path) |
| 57 | + end |
| 58 | + |
| 59 | + def populate_resource_cache(app_packager, app_contents_path) |
| 60 | + FileUtils.mkdir(app_contents_path) |
| 61 | + app_packager.unzip(app_contents_path) |
| 62 | + |
| 63 | + remove_symlinks(app_contents_path) |
| 64 | + |
| 65 | + global_app_bits_cache.cp_r_to_blobstore(app_contents_path) |
| 66 | + end |
| 67 | + |
| 68 | + def remove_symlinks(app_contents_path) |
| 69 | + Find.find(app_contents_path) do |path| |
| 70 | + File.delete(path) if File.symlink?(path) |
| 71 | + end |
| 72 | + end |
| 73 | + |
| 74 | + def append_matched_resources(app_packager, cached_files_fingerprints, root_path) |
| 75 | + matched_resources = CloudController::Blobstore::FingerprintsCollection.new(cached_files_fingerprints, root_path) |
| 76 | + cached_resources_dir = File.join(root_path, 'cached_resources_dir') |
| 77 | + |
| 78 | + FileUtils.mkdir(cached_resources_dir) |
| 79 | + checksum_mismatch = false |
| 80 | + matched_resources.each do |local_destination, file_sha, mode| |
| 81 | + file_path = File.join(cached_resources_dir, local_destination) |
| 82 | + global_app_bits_cache.download_from_blobstore(file_sha, File.join(cached_resources_dir, local_destination), mode:) |
| 83 | + |
| 84 | + if Digester.new.digest_path(file_path) != file_sha |
| 85 | + checksum_mismatch = true |
| 86 | + global_app_bits_cache.delete(file_sha) |
| 87 | + end |
| 88 | + end |
| 89 | + |
| 90 | + raise CloudController::Errors::ApiError.new_from_details('ResourceChecksumMismatch') if checksum_mismatch |
| 91 | + |
| 92 | + app_packager.append_dir_contents(cached_resources_dir) |
| 93 | + end |
| 94 | + |
| 95 | + def match_resources_and_validate_package(root_path, uploaded_package_zip, cached_files_fingerprints) |
| 96 | + app_packager = AppPackager.new(File.join(root_path, 'copied_app_package.zip')) |
| 97 | + app_contents_path = File.join(root_path, 'application_contents') |
| 98 | + |
| 99 | + if package_zip_exists?(uploaded_package_zip) |
| 100 | + copy_uploaded_package(uploaded_package_zip, app_packager) |
| 101 | + validate_size!(app_packager) |
| 102 | + populate_resource_cache(app_packager, app_contents_path) unless VCAP::CloudController::FeatureFlag.disabled?(:resource_matching) |
| 103 | + end |
| 104 | + |
| 105 | + append_matched_resources(app_packager, cached_files_fingerprints, root_path) |
| 106 | + |
| 107 | + validate_size!(app_packager) |
| 108 | + app_packager.fix_subdir_permissions(root_path, app_contents_path) |
| 109 | + app_packager.path |
| 110 | + end |
| 111 | + |
| 112 | + def max_package_size |
| 113 | + VCAP::CloudController::Config.config.get(:packages, :max_package_size) |
| 114 | + end |
| 115 | + |
| 116 | + def global_app_bits_cache |
| 117 | + CloudController::DependencyLocator.instance.global_app_bits_cache |
| 118 | + end |
42 | 119 | end
|
43 | 120 | end
|
44 | 121 | end
|
0 commit comments