<commit_before>#include S3File

require 'digest/md5'
require 'rest-client'
require 'json'

action :create do
  new_resource = @new_resource
  download = true
  
  # handle key specified without leading slash
  remote_path = new_resource.remote_path
  if remote_path.chars.first != '/'
    remote_path = "/#{remote_path}"
  end
  
  # we need credentials to be mutable
  aws_access_key_id = new_resource.aws_access_key_id
  aws_secret_access_key = new_resource.aws_secret_access_key
  token = new_resource.token
  
  # if credentials not set, try instance profile
  if new_resource.aws_access_key_id.nil? and new_resource.aws_secret_access_key.nil? and new_resource.token.nil?
    instance_profile_base_url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/'
    begin
      instance_profiles = RestClient.get(instance_profile_base_url)
    rescue RestClient::ResourceNotFound, Errno::ETIMEDOUT # we can either 404 on an EC2 instance, or timeout on non-EC2
      raise ArgumentError.new 'No credentials provided and no instance profile on this machine.'
    end
    instance_profile_name = instance_profiles.split.first
    instance_profile = JSON.load(RestClient.get(instance_profile_base_url + instance_profile_name))
    
    aws_access_key_id = instance_profile['AccessKeyId']
    aws_secret_access_key = instance_profile['SecretAccessKey']
    token = instance_profile['Token']
  end
    
  if ::File.exists? new_resource.path
    s3_md5 = S3FileLib::get_md5_from_s3(new_resource.bucket, remote_path, aws_access_key_id, aws_secret_access_key, token)
    
    current_md5 = Digest::MD5.hexdigest(::File.read(new_resource.path))
    
    Chef::Log.debug "md5 of S3 object is #{s3_md5}"
    Chef::Log.debug "md5 of local object is #{current_md5}"
    
    if current_md5 == s3_md5 then
      Chef::Log.debug 'Skipping download, md5sum of local file matches file in S3.'
      download = false
    end
  end
  
  if download
    response = S3FileLib::get_from_s3(new_resource.bucket, remote_path, aws_access_key_id, aws_secret_access_key, token)

    # not simply using the file resource here because we would have to buffer whole file into memory in order to set content
    # this solves https://github.com/adamsb6/s3_file/issues/15
    mode = new_resource.mode || 0644
    mode = mode.is_a?(String) ? mode.to_i : mode
    
    owner = new_resource.owner || ENV['user']
    group = new_resource.group || ENV['user']
    
    ::FileUtils.mv response.file.path, new_resource.path
    ::FileUtils.chown owner, group, [ new_resource.path ]
    ::FileUtils.chmod mode, [ new_resource.path ]
    
    @new_resource.updated_by_last_action(true)
  end
end<commit_msg>Fixed conversion of mode from string to integer. Mode string is now converted to octal integer.<commit_after>#include S3File

require 'digest/md5'
require 'rest-client'
require 'json'

action :create do
  new_resource = @new_resource
  download = true
  
  # handle key specified without leading slash
  remote_path = new_resource.remote_path
  if remote_path.chars.first != '/'
    remote_path = "/#{remote_path}"
  end
  
  # we need credentials to be mutable
  aws_access_key_id = new_resource.aws_access_key_id
  aws_secret_access_key = new_resource.aws_secret_access_key
  token = new_resource.token
  
  # if credentials not set, try instance profile
  if new_resource.aws_access_key_id.nil? and new_resource.aws_secret_access_key.nil? and new_resource.token.nil?
    instance_profile_base_url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/'
    begin
      instance_profiles = RestClient.get(instance_profile_base_url)
    rescue RestClient::ResourceNotFound, Errno::ETIMEDOUT # we can either 404 on an EC2 instance, or timeout on non-EC2
      raise ArgumentError.new 'No credentials provided and no instance profile on this machine.'
    end
    instance_profile_name = instance_profiles.split.first
    instance_profile = JSON.load(RestClient.get(instance_profile_base_url + instance_profile_name))
    
    aws_access_key_id = instance_profile['AccessKeyId']
    aws_secret_access_key = instance_profile['SecretAccessKey']
    token = instance_profile['Token']
  end
    
  if ::File.exists? new_resource.path
    s3_md5 = S3FileLib::get_md5_from_s3(new_resource.bucket, remote_path, aws_access_key_id, aws_secret_access_key, token)
    
    current_md5 = Digest::MD5.hexdigest(::File.read(new_resource.path))
    
    Chef::Log.debug "md5 of S3 object is #{s3_md5}"
    Chef::Log.debug "md5 of local object is #{current_md5}"
    
    if current_md5 == s3_md5 then
      Chef::Log.debug 'Skipping download, md5sum of local file matches file in S3.'
      download = false
    end
  end
  
  if download
    response = S3FileLib::get_from_s3(new_resource.bucket, remote_path, aws_access_key_id, aws_secret_access_key, token)

    # not simply using the file resource here because we would have to buffer whole file into memory in order to set content
    # this solves https://github.com/adamsb6/s3_file/issues/15
    mode = new_resource.mode || 0644
    mode = mode.is_a?(String) ? mode.to_i(8) : mode
    
    owner = new_resource.owner || ENV['user']
    group = new_resource.group || ENV['user']
    
    ::FileUtils.mv response.file.path, new_resource.path
    ::FileUtils.chown owner, group, [ new_resource.path ]
    ::FileUtils.chmod mode, [ new_resource.path ]
    
    @new_resource.updated_by_last_action(true)
  end
end
{'fraction_non_alphanumeric': 0.08745177291934594, 'fraction_numerical': 0.017453610141466104, 'mean_word_length': 4.050092764378479, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7420618', 'n_tokens_mistral': 1799, 'n_tokens_neox': 1774, 'n_words': 416}