Class | BoxGrinder::S3Plugin |
In: |
lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb
lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb |
Parent: | BasePlugin |
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 32 32: def after_init 33: @ami_build_dir = "#{@dir.base}/ami" 34: @ami_manifest = "#{@ami_build_dir}/#{@appliance_config.name}.ec2.manifest.xml" 35: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 32 32: def after_init 33: @ami_build_dir = "#{@dir.base}/ami" 34: @ami_manifest = "#{@ami_build_dir}/#{@appliance_config.name}.ec2.manifest.xml" 35: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 222 222: def ami_by_manifest_key(ami_manifest_key) 223: ami = @ec2.images.with_owner(@plugin_config['account_number']). 224: filter("manifest-location","#{@plugin_config['bucket']}/#{ami_manifest_key.key}") 225: return nil unless ami.any? 226: ami.first 227: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 222 222: def ami_by_manifest_key(ami_manifest_key) 223: ami = @ec2.images.with_owner(@plugin_config['account_number']). 224: filter("manifest-location","#{@plugin_config['bucket']}/#{ami_manifest_key.key}") 225: return nil unless ami.any? 226: ami.first 227: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 229 229: def ami_key(appliance_name, path) 230: base_path = "#{@s3helper.parse_path(path)}#{appliance_name}/#{@appliance_config.os.name}/#{@appliance_config.os.version}/#{@appliance_config.version}.#{@appliance_config.release}" 231: 232: return "#{base_path}/#{@appliance_config.hardware.arch}" unless @plugin_config['snapshot'] 233: 234: @log.info "Determining snapshot name" 235: snapshot = 1 236: while @s3helper.stub_s3obj(@bucket, "#{base_path}-snapshot-#{snapshot}/#{@appliance_config.hardware.arch}/").exists? 237: snapshot += 1 238: end 239: # Reuse the last key (if there was one) 240: snapshot -=1 if snapshot > 1 and @plugin_config['overwrite'] 241: 242: "#{base_path}-snapshot-#{snapshot}/#{@appliance_config.hardware.arch}" 243: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 229 229: def ami_key(appliance_name, path) 230: base_path = "#{@s3helper.parse_path(path)}#{appliance_name}/#{@appliance_config.os.name}/#{@appliance_config.os.version}/#{@appliance_config.version}.#{@appliance_config.release}" 231: 232: return "#{base_path}/#{@appliance_config.hardware.arch}" unless @plugin_config['snapshot'] 233: 234: @log.info "Determining snapshot name" 235: snapshot = 1 236: while @s3helper.stub_s3obj(@bucket, "#{base_path}-snapshot-#{snapshot}/#{@appliance_config.hardware.arch}/").exists? 237: snapshot += 1 238: end 239: # Reuse the last key (if there was one) 240: snapshot -=1 if snapshot > 1 and @plugin_config['overwrite'] 241: 242: "#{base_path}-snapshot-#{snapshot}/#{@appliance_config.hardware.arch}" 243: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 143 143: def asset_bucket(create_if_missing = true, permissions = :private) 144: @s3helper.bucket(:bucket => @plugin_config['bucket'], 145: :create_if_missing => create_if_missing, 146: :acl => permissions, 147: :location_constraint => @s3_endpoints[@plugin_config['region']][:location] 148: ) 149: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 143 143: def asset_bucket(create_if_missing = true, permissions = :private) 144: @s3helper.bucket(:bucket => @plugin_config['bucket'], 145: :create_if_missing => create_if_missing, 146: :acl => permissions, 147: :location_constraint => @s3_endpoints[@plugin_config['region']][:location] 148: ) 149: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 151 151: def bundle_image(deliverables) 152: if @plugin_config['snapshot'] 153: @log.debug "Removing bundled image from local disk..." 154: FileUtils.rm_rf(@ami_build_dir) 155: end 156: 157: return if File.exists?(@ami_build_dir) 158: 159: @log.info "Bundling AMI..." 160: 161: FileUtils.mkdir_p(@ami_build_dir) 162: 163: cmd_str = "euca-bundle-image --ec2cert #{File.dirname(__FILE__)}/src/cert-ec2.pem " << 164: "-i #{deliverables[:disk]} " << 165: "--kernel #{@plugin_config['kernel'] || @s3_endpoints[@plugin_config['region']][:kernel][@appliance_config.hardware.base_arch.intern][:aki]} " << 166: "-c #{@plugin_config['cert_file']} "<< 167: "-k #{@plugin_config['key_file']} " << 168: "-u #{@plugin_config['account_number']} " << 169: "-r #{@appliance_config.hardware.base_arch} " << 170: "-d #{@ami_build_dir} " 171: 172: cmd_str << "--ramdisk #{@plugin_config['ramdisk']}" if @plugin_config['ramdisk'] 173: 174: @exec_helper.execute(cmd_str, :redacted => [@plugin_config['account_number'], @plugin_config['key_file'], @plugin_config['cert_file']]) 175: 176: @log.info "Bundling AMI finished." 177: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 151 151: def bundle_image(deliverables) 152: if @plugin_config['snapshot'] 153: @log.debug "Removing bundled image from local disk..." 154: FileUtils.rm_rf(@ami_build_dir) 155: end 156: 157: return if File.exists?(@ami_build_dir) 158: 159: @log.info "Bundling AMI..." 160: 161: FileUtils.mkdir_p(@ami_build_dir) 162: 163: cmd_str = "euca-bundle-image --ec2cert #{File.dirname(__FILE__)}/src/cert-ec2.pem " << 164: "-i #{deliverables[:disk]} " << 165: "--kernel #{@plugin_config['kernel'] || @s3_endpoints[@plugin_config['region']][:kernel][@appliance_config.hardware.base_arch.intern][:aki]} " << 166: "-c #{@plugin_config['cert_file']} "<< 167: "-k #{@plugin_config['key_file']} " << 168: "-u #{@plugin_config['account_number']} " << 169: "-r #{@appliance_config.hardware.base_arch} " << 170: "-d #{@ami_build_dir} " 171: 172: cmd_str << "--ramdisk #{@plugin_config['ramdisk']}" if @plugin_config['ramdisk'] 173: 174: @exec_helper.execute(cmd_str, :redacted => [@plugin_config['account_number'], @plugin_config['key_file'], @plugin_config['cert_file']]) 175: 176: @log.info "Bundling AMI finished." 177: end
US default constraint is often represented as ’’ or nil
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 246 246: def constraint_equal?(region, constraint) 247: [region, constraint].collect{ |v| v.nil? || v == '' ? 'us-east-1' : v }.reduce(:==) 248: end
US default constraint is often represented as ’’ or nil
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 246 246: def constraint_equal?(region, constraint) 247: [region, constraint].collect{ |v| v.nil? || v == '' ? 'us-east-1' : v }.reduce(:==) 248: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 212 212: def deregister_image(ami_manifest_key) 213: if ami = ami_by_manifest_key(ami_manifest_key) 214: @log.info "Preexisting image '#{ami.location}' for #{@appliance_config.name} will be de-registered, it had id: #{ami.id} (region: #{@plugin_config['region']})." 215: ami.deregister 216: @ec2helper.wait_for_image_death(ami) 217: else # This occurs when the AMI is de-registered externally but the file structure is left intact in S3. In this instance, we simply overwrite and register the image as if it were "new". 218: @log.debug "Possible dangling/unregistered AMI skeleton structure in S3, there is nothing to deregister" 219: end 220: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 212 212: def deregister_image(ami_manifest_key) 213: if ami = ami_by_manifest_key(ami_manifest_key) 214: @log.info "Preexisting image '#{ami.location}' for #{@appliance_config.name} will be de-registered, it had id: #{ami.id} (region: #{@plugin_config['region']})." 215: ami.deregister 216: @ec2helper.wait_for_image_death(ami) 217: else # This occurs when the AMI is de-registered externally but the file structure is left intact in S3. In this instance, we simply overwrite and register the image as if it were "new". 218: @log.debug "Possible dangling/unregistered AMI skeleton structure in S3, there is nothing to deregister" 219: end 220: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 87 87: def execute 88: case @type 89: when :s3 90: upload_to_bucket(@previous_deliverables) 91: when :cloudfront 92: upload_to_bucket(@previous_deliverables, :public_read) 93: when :ami 94: @log.info Banner.message(S3::Messages::EPHEMERAL_MESSAGE) 95: 96: ami_dir = ami_key(@appliance_config.name, @plugin_config['path']) 97: ami_manifest_key = @s3helper.stub_s3obj(@bucket, "#{ami_dir}/#{@appliance_config.name}.ec2.manifest.xml") 98: 99: @log.debug "Going to check whether s3 object exists" 100: 101: if ami_manifest_key.exists? and @plugin_config['overwrite'] 102: @log.info "Object exists, attempting to deregister an existing image" 103: deregister_image(ami_manifest_key) # Remove existing image 104: @s3helper.delete_folder(@bucket, ami_dir) # Avoid triggering dupe detection 105: end 106: 107: if !ami_manifest_key.exists? or @plugin_config['snapshot'] 108: @log.info "Doing bundle/snapshot" 109: bundle_image(@previous_deliverables) 110: upload_image(ami_dir) 111: end 112: register_image(ami_manifest_key) 113: end 114: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 87 87: def execute 88: case @type 89: when :s3 90: upload_to_bucket(@previous_deliverables) 91: when :cloudfront 92: upload_to_bucket(@previous_deliverables, :public_read) 93: when :ami 94: @log.info Banner.message(S3::Messages::EPHEMERAL_MESSAGE) 95: 96: ami_dir = ami_key(@appliance_config.name, @plugin_config['path']) 97: ami_manifest_key = @s3helper.stub_s3obj(@bucket, "#{ami_dir}/#{@appliance_config.name}.ec2.manifest.xml") 98: 99: @log.debug "Going to check whether s3 object exists" 100: 101: if ami_manifest_key.exists? and @plugin_config['overwrite'] 102: @log.info "Object exists, attempting to deregister an existing image" 103: deregister_image(ami_manifest_key) # Remove existing image 104: @s3helper.delete_folder(@bucket, ami_dir) # Avoid triggering dupe detection 105: end 106: 107: if !ami_manifest_key.exists? or @plugin_config['snapshot'] 108: @log.info "Doing bundle/snapshot" 109: bundle_image(@previous_deliverables) 110: upload_image(ami_dir) 111: end 112: register_image(ami_manifest_key) 113: end 114: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 194 194: def register_image(ami_manifest_key) 195: if ami = ami_by_manifest_key(ami_manifest_key) 196: @log.info "Image for #{@appliance_config.name} is already registered under id: #{ami.id} (region: #{@plugin_config['region']})." 197: else 198: optmap = { :image_location => "#{@plugin_config['bucket']}/#{ami_manifest_key.key}" } 199: 200: unless @plugin_config['block_device_mappings'].empty? 201: optmap.merge!(:block_device_mappings => @plugin_config['block_device_mappings']) 202: end 203: 204: @log.debug("Options map: #{optmap.inspect}") 205: 206: ami = @ec2.images.create(optmap) 207: @ec2helper.wait_for_image_state(:available, ami) 208: @log.info "Image for #{@appliance_config.name} successfully registered under id: #{ami.id} (region: #{@plugin_config['region']})." 209: end 210: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 194 194: def register_image(ami_manifest_key) 195: if ami = ami_by_manifest_key(ami_manifest_key) 196: @log.info "Image for #{@appliance_config.name} is already registered under id: #{ami.id} (region: #{@plugin_config['region']})." 197: else 198: optmap = { :image_location => "#{@plugin_config['bucket']}/#{ami_manifest_key.key}" } 199: 200: unless @plugin_config['block_device_mappings'].empty? 201: optmap.merge!(:block_device_mappings => @plugin_config['block_device_mappings']) 202: end 203: 204: @log.debug("Options map: #{optmap.inspect}") 205: 206: ami = @ec2.images.create(optmap) 207: @ec2helper.wait_for_image_state(:available, ami) 208: @log.info "Image for #{@appliance_config.name} successfully registered under id: #{ami.id} (region: #{@plugin_config['region']})." 209: end 210: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 179 179: def upload_image(ami_dir) 180: @log.info "Uploading #{@appliance_config.name} AMI to bucket '#{@plugin_config['bucket']}'..." 181: 182: endpoint = @plugin_config['url'] || "http://#{@s3_endpoints[@plugin_config['region']][:endpoint]}" 183: 184: cmd_str = "euca-upload-bundle " << 185: "-U #{endpoint} " << 186: "-b #{@plugin_config['bucket']}/#{ami_dir} " << 187: "-m #{@ami_manifest} " << 188: "-a #{@plugin_config['access_key']} " << 189: "-s #{@plugin_config['secret_access_key']}" 190: 191: @exec_helper.execute(cmd_str, :redacted => [@plugin_config['access_key'], @plugin_config['secret_access_key']]) 192: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 179 179: def upload_image(ami_dir) 180: @log.info "Uploading #{@appliance_config.name} AMI to bucket '#{@plugin_config['bucket']}'..." 181: 182: endpoint = @plugin_config['url'] || "http://#{@s3_endpoints[@plugin_config['region']][:endpoint]}" 183: 184: cmd_str = "euca-upload-bundle " << 185: "-U #{endpoint} " << 186: "-b #{@plugin_config['bucket']}/#{ami_dir} " << 187: "-m #{@ami_manifest} " << 188: "-a #{@plugin_config['access_key']} " << 189: "-s #{@plugin_config['secret_access_key']}" 190: 191: @exec_helper.execute(cmd_str, :redacted => [@plugin_config['access_key'], @plugin_config['secret_access_key']]) 192: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 116 116: def upload_to_bucket(previous_deliverables, permissions = :private) 117: register_deliverable( 118: :package => "#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}-#{@appliance_config.os.name}-#{@appliance_config.os.version}-#{@appliance_config.hardware.arch}-#{current_platform}.tgz" 119: ) 120: 121: # quick and dirty workaround to use @deliverables[:package] later in code 122: FileUtils.mv(@target_deliverables[:package], @deliverables[:package]) if File.exists?(@target_deliverables[:package]) 123: 124: PackageHelper.new(@config, @appliance_config, :log => @log, :exec_helper => @exec_helper).package(File.dirname(previous_deliverables[:disk]), @deliverables[:package]) 125: 126: remote_path = "#{@s3helper.parse_path(@plugin_config['path'])}#{File.basename(@deliverables[:package])}" 127: size_m = File.size(@deliverables[:package])/1024**2 128: s3_obj = @s3helper.stub_s3obj(@bucket,remote_path.gsub(/^\//, '').gsub(/\/\//, '')) 129: # Does it really exist? 130: obj_exists = s3_obj.exists? 131: 132: if !obj_exists or @plugin_config['overwrite'] 133: @log.info "Will overwrite existing file #{remote_path}" if obj_exists and @plugin_config['overwrite'] 134: @log.info "Uploading #{File.basename(@deliverables[:package])} (#{size_m}MB) to '#{@plugin_config['bucket']}#{remote_path}' path..." 135: s3_obj.write(:file => @deliverables[:package], 136: :acl => permissions) 137: @log.info "Appliance #{@appliance_config.name} uploaded to S3." 138: else 139: @log.info "File '#{@plugin_config['bucket']}#{remote_path}' already uploaded, skipping." 140: end 141: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 116 116: def upload_to_bucket(previous_deliverables, permissions = :private) 117: register_deliverable( 118: :package => "#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}-#{@appliance_config.os.name}-#{@appliance_config.os.version}-#{@appliance_config.hardware.arch}-#{current_platform}.tgz" 119: ) 120: 121: # quick and dirty workaround to use @deliverables[:package] later in code 122: FileUtils.mv(@target_deliverables[:package], @deliverables[:package]) if File.exists?(@target_deliverables[:package]) 123: 124: PackageHelper.new(@config, @appliance_config, :log => @log, :exec_helper => @exec_helper).package(File.dirname(previous_deliverables[:disk]), @deliverables[:package]) 125: 126: remote_path = "#{@s3helper.parse_path(@plugin_config['path'])}#{File.basename(@deliverables[:package])}" 127: size_m = File.size(@deliverables[:package])/1024**2 128: s3_obj = @s3helper.stub_s3obj(@bucket,remote_path.gsub(/^\//, '').gsub(/\/\//, '')) 129: # Does it really exist? 130: obj_exists = s3_obj.exists? 131: 132: if !obj_exists or @plugin_config['overwrite'] 133: @log.info "Will overwrite existing file #{remote_path}" if obj_exists and @plugin_config['overwrite'] 134: @log.info "Uploading #{File.basename(@deliverables[:package])} (#{size_m}MB) to '#{@plugin_config['bucket']}#{remote_path}' path..." 135: s3_obj.write(:file => @deliverables[:package], 136: :acl => permissions) 137: @log.info "Appliance #{@appliance_config.name} uploaded to S3." 138: else 139: @log.info "File '#{@plugin_config['bucket']}#{remote_path}' already uploaded, skipping." 140: end 141: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 37 37: def validate 38: set_default_config_value('overwrite', false) 39: set_default_config_value('kernel', false) 40: set_default_config_value('ramdisk', false) 41: set_default_config_value('path', '/') 42: set_default_config_value('region', 'us-east-1') 43: 44: set_default_config_value('block_device_mappings', {}) do |k, m, v| 45: EC2Helper::block_device_mappings_validator(k, m, v) 46: end 47: 48: validate_plugin_config(['bucket', 'access_key', 'secret_access_key'], 'http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#S3_Delivery_Plugin') 49: 50: subtype(:ami) do 51: set_default_config_value('snapshot', false) 52: validate_plugin_config(['cert_file', 'key_file', 'account_number'], 'http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#S3_Delivery_Plugin') 53: 54: raise PluginValidationError, "AWS certificate file doesn't exists, please check the path: '#{@plugin_config['cert_file']}'." unless File.exists?(File.expand_path(@plugin_config['cert_file'])) 55: raise PluginValidationError, "AWS key file doesn't exists, please check the path: '#{@plugin_config['key_file']}'." unless File.exists?(File.expand_path(@plugin_config['key_file'])) 56: end 57: 58: @s3_endpoints = S3Helper::endpoints 59: raise PluginValidationError, "Invalid region specified: #{@plugin_config['region']}. This plugin is only aware of the following regions: #{@s3_endpoints.keys.join(", ")}." unless @s3_endpoints.has_key?(@plugin_config['region']) 60: 61: @plugin_config['account_number'] = @plugin_config['account_number'].to_s.gsub(/-/, '') 62: 63: # Set global AWS configuration 64: AWS.config(:access_key_id => @plugin_config['access_key'], 65: :secret_access_key => @plugin_config['secret_access_key'], 66: :ec2_endpoint => EC2Helper::endpoints[@plugin_config['region']][:endpoint], 67: :s3_endpoint => @s3_endpoints[@plugin_config['region']][:endpoint], 68: :max_retries => 5, 69: :use_ssl => @plugin_config['use_ssl']) 70: 71: @ec2 = AWS::EC2.new 72: @s3 = AWS::S3.new 73: @s3helper = S3Helper.new(@ec2, @s3, :log => @log) 74: @ec2helper = EC2Helper.new(@ec2, :log => @log) 75: 76: subtype(:ami) do 77: # If there is an existing bucket, determine whether its location_constraint matches the region selected 78: if existing_bucket = asset_bucket(false) 79: raise PluginValidationError, "Existing bucket #{@plugin_config['bucket']} has a location constraint that does not match the region selected. " << 80: "AMI region and bucket location constraint must match." unless constraint_equal?(@plugin_config['region'], existing_bucket.location_constraint) 81: end 82: end 83: 84: @bucket = asset_bucket(true) 85: end
# File lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb, line 37 37: def validate 38: set_default_config_value('overwrite', false) 39: set_default_config_value('kernel', false) 40: set_default_config_value('ramdisk', false) 41: set_default_config_value('path', '/') 42: set_default_config_value('region', 'us-east-1') 43: 44: set_default_config_value('block_device_mappings', {}) do |k, m, v| 45: EC2Helper::block_device_mappings_validator(k, m, v) 46: end 47: 48: validate_plugin_config(['bucket', 'access_key', 'secret_access_key'], 'http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#S3_Delivery_Plugin') 49: 50: subtype(:ami) do 51: set_default_config_value('snapshot', false) 52: validate_plugin_config(['cert_file', 'key_file', 'account_number'], 'http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#S3_Delivery_Plugin') 53: 54: raise PluginValidationError, "AWS certificate file doesn't exists, please check the path: '#{@plugin_config['cert_file']}'." unless File.exists?(File.expand_path(@plugin_config['cert_file'])) 55: raise PluginValidationError, "AWS key file doesn't exists, please check the path: '#{@plugin_config['key_file']}'." unless File.exists?(File.expand_path(@plugin_config['key_file'])) 56: end 57: 58: @s3_endpoints = S3Helper::endpoints 59: raise PluginValidationError, "Invalid region specified: #{@plugin_config['region']}. This plugin is only aware of the following regions: #{@s3_endpoints.keys.join(", ")}." unless @s3_endpoints.has_key?(@plugin_config['region']) 60: 61: @plugin_config['account_number'] = @plugin_config['account_number'].to_s.gsub(/-/, '') 62: 63: # Set global AWS configuration 64: AWS.config(:access_key_id => @plugin_config['access_key'], 65: :secret_access_key => @plugin_config['secret_access_key'], 66: :ec2_endpoint => EC2Helper::endpoints[@plugin_config['region']][:endpoint], 67: :s3_endpoint => @s3_endpoints[@plugin_config['region']][:endpoint], 68: :max_retries => 5, 69: :use_ssl => @plugin_config['use_ssl']) 70: 71: @ec2 = AWS::EC2.new 72: @s3 = AWS::S3.new 73: @s3helper = S3Helper.new(@ec2, @s3, :log => @log) 74: @ec2helper = EC2Helper.new(@ec2, :log => @log) 75: 76: subtype(:ami) do 77: # If there is an existing bucket, determine whether its location_constraint matches the region selected 78: if existing_bucket = asset_bucket(false) 79: raise PluginValidationError, "Existing bucket #{@plugin_config['bucket']} has a location constraint that does not match the region selected. " << 80: "AMI region and bucket location constraint must match." unless constraint_equal?(@plugin_config['region'], existing_bucket.location_constraint) 81: end 82: end 83: 84: @bucket = asset_bucket(true) 85: end