Class: Capistrano::SCM::S3Archive::LocalCache

Inherits:
Object
  • Object
show all
Includes:
FileUtils
Defined in:
lib/capistrano/scm/s3_archive/local_cache.rb

Defined Under Namespace

Classes: ResourceBusyError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(backend, download_dir, cache_dir, archive_object) ⇒ LocalCache

Returns a new instance of LocalCache.



9
10
11
12
13
14
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 9

def initialize(backend, download_dir, cache_dir, archive_object)
  @backend = backend
  @download_dir = download_dir
  @cache_dir = cache_dir
  @archive_object = archive_object
end

Instance Attribute Details

#archive_objectObject (readonly)

Returns the value of attribute archive_object.



5
6
7
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 5

def archive_object
  @archive_object
end

#backendObject (readonly)

Returns the value of attribute backend.



5
6
7
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 5

def backend
  @backend
end

#cache_dirObject (readonly)

Returns the value of attribute cache_dir.



5
6
7
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 5

def cache_dir
  @cache_dir
end

#download_dirObject (readonly)

Returns the value of attribute download_dir.



5
6
7
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 5

def download_dir
  @download_dir
end

Instance Method Details

#all_file_exist?(arr) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 64

def all_file_exist?(arr)
  arr.all?(&File.method(:exist?))
end

#cleanup(keep: 0) ⇒ Object



49
50
51
52
53
54
55
56
57
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 49

def cleanup(keep: 0)
  downloaded_files = Dir.glob(File.join(download_dir, '*')).sort_by(&File.method(:mtime))
  return if downloaded_files.count <= keep

  remove_keys = (downloaded_files - downloaded_files.last(keep)).map { |f| File.basename(f, '.*') }.flat_map { |f| ["#{f}*", ".#{f}*"] }
  to_be_removes = Dir.glob(remove_keys, base: download_dir).map { |f| File.join(download_dir, f) }

  remove(to_be_removes, force: true, verbose: true)
end

#downloadObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 16

def download
  download_lock do
    tmp_file = "#{target_file}.part"
    etag_file = File.join(download_dir, ".#{archive_object.key_basename}.etag")
    raise "#{tmp_file} is found. Another process is running?" if File.exist?(tmp_file)

    if all_file_exist?([target_file, etag_file]) && File.read(etag_file) == archive_object.etag
      backend.info "#{target_file} (etag:#{archive_object.etag}) is found. download skipped."
    else
      backend.info "Download s3://#{archive_object.bucket}/#{archive_object.key} to #{target_file}"
      mkdir_p(File.dirname(target_file))
      File.open(tmp_file, 'w') do |file|
        archive_object.get_object(file)
      end
      move(tmp_file, target_file)
      File.write(etag_file, archive_object.etag)
    end
  end
end

#download_lock(&block) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 68

def download_lock(&block)
  mkdir_p(File.dirname(download_dir))
  lockfile = "#{download_dir}.lock"
  begin
    File.open(lockfile, "w") do |file|
      raise ResourceBusyError, "Could not get #{lockfile}" unless file.flock(File::LOCK_EX | File::LOCK_NB)

      block.call
    end
  ensure
    rm lockfile if File.exist? lockfile
  end
end

#extractObject



36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 36

def extract
  remove_entry_secure(cache_dir) if File.exist?(cache_dir)
  mkdir_p(cache_dir)
  case target_file
  when /\.zip\?.*\Z/
    cmd = "unzip -q -d #{cache_dir} #{target_file}"
  when /\.tar\.gz\?.*\Z|\.tar\.bz2\?.*\Z|\.tgz\?.*\Z/
    cmd = "tar xf #{target_file} -C #{cache_dir}"
  end

  backend.execute cmd # should I use `execute`?
end

#target_fileObject



59
60
61
62
# File 'lib/capistrano/scm/s3_archive/local_cache.rb', line 59

def target_file
  basename = [archive_object.key_basename, archive_object.version_id].join('?')
  File.join(download_dir, basename)
end