Class: Capistrano::Deploy::Strategy::Copy

Class | Capistrano::Deploy::Strategy::Copy
In: | lib/capistrano/recipes/deploy/strategy/copy.rb lib/capistrano/recipes/deploy/strategy/copy.rb
Parent: | Base

This class implements the strategy for deployments which work by preparing the source code locally, compressing it, copying the file to each target host, and uncompressing it to the deployment directory.

By default, the SCM checkout command is used to obtain the local copy of the source code. If you would rather use the export operation, you can set the :copy_strategy variable to :export.

      set :copy_strategy, :export

For even faster deployments, you can set the :copy_cache variable to true. This will cause deployments to do a new checkout of your repository to a new directory, and then copy that checkout. Subsequent deploys will just resync that copy, rather than doing an entirely new checkout. Additionally, you can specify file patterns to exclude from the copy when using :copy_cache; just set the :copy_exclude variable to a file glob (or an array of globs).

      set :copy_cache, true
      set :copy_exclude, ".git/*"

Note that :copy_strategy is ignored when :copy_cache is set. Also, if you want the copy cache put somewhere specific, you can set the variable to the path you want, instead of merely ‘true’:

      set :copy_cache, "/tmp/caches/myapp"

This deployment strategy also supports a special variable, :copy_compression, which must be one of :gzip, :bz2, or :zip, and which specifies how the source should be compressed for transmission to each host.

### Methods

check! check! copy_cache copy_cache deploy! deploy!

### Constants

Compression | = | Struct.new(:extension, :compress_command, :decompress_command) |  | A struct for representing the specifics of a compression type. Commands are arrays, where the first element is the utility to be used to perform the compression or decompression.
Compression | = | Struct.new(:extension, :compress_command, :decompress_command) |  | A struct for representing the specifics of a compression type. Commands are arrays, where the first element is the utility to be used to perform the compression or decompression.

### Public Instance methods

check!()

[Source]

         # File lib/capistrano/recipes/deploy/strategy/copy.rb, line 106
    106:         def check!
    107:           super.check do |d|
    108:             d.local.command(source.local.command) if source.local.command
    109:             d.local.command(compress(nil, nil).first)
    110:             d.remote.command(decompress(nil).first)
    111:           end
    112:         end

check!()

[Source]

         # File lib/capistrano/recipes/deploy/strategy/copy.rb, line 106
    106:         def check!
    107:           super.check do |d|
    108:             d.local.command(source.local.command) if source.local.command
    109:             d.local.command(compress(nil, nil).first)
    110:             d.remote.command(decompress(nil).first)
    111:           end
    112:         end

copy_cache()

Returns the location of the local copy cache, if the strategy should use a local cache + copy instead of a new checkout/export every time. Returns `nil` unless :copy_cache has been set. If :copy_cache is `true`, a default cache location will be returned.

[Source]

         # File lib/capistrano/recipes/deploy/strategy/copy.rb, line 118
    118:         def copy_cache
    119:           @copy_cache ||= configuration[:copy_cache] == true ?
    120:             File.join(Dir.tmpdir, configuration[:application]) :
    121:             configuration[:copy_cache]
    122:         end

copy_cache()

Returns the location of the local copy cache, if the strategy should use a local cache + copy instead of a new checkout/export every time. Returns `nil` unless :copy_cache has been set. If :copy_cache is `true`, a default cache location will be returned.

[Source]

         # File lib/capistrano/recipes/deploy/strategy/copy.rb, line 118
    118:         def copy_cache
    119:           @copy_cache ||= configuration[:copy_cache] == true ?
    120:             File.join(Dir.tmpdir, configuration[:application]) :
    121:             configuration[:copy_cache]
    122:         end

deploy!()

Obtains a copy of the source code locally (via the command method), compresses it to a single file, copies that file to all target servers, and uncompresses it on each of them into the deployment directory.

[Source]

         # File lib/capistrano/recipes/deploy/strategy/copy.rb, line 46
     46:         def deploy!
     47:           if copy_cache
     48:             if File.exists?(copy_cache)
     49:               logger.debug "refreshing local cache to revision #{revision} at #{copy_cache}"
     50:               system(source.sync(revision, copy_cache))
     51:             else
     52:               logger.debug "preparing local cache at #{copy_cache}"
     53:               system(source.checkout(revision, copy_cache))
     54:             end
     55:
     56:             logger.debug "copying cache to deployment staging area #{destination}"
     57:             Dir.chdir(copy_cache) do
     58:               FileUtils.mkdir_p(destination)
     59:               queue = Dir.glob("*", File::FNM_DOTMATCH)
     60:               while queue.any?
     61:                 item = queue.shift
     62:                 name = File.basename(item)
     63:
     64:                 next if name == "." || name == ".."
     65:                 next if copy_exclude.any? { |pattern| File.fnmatch(pattern, item) }
     66:
     67:                 if File.symlink?(item)
     68:                   FileUtils.ln_s(File.readlink(File.join(copy_cache, item)), File.join(destination, item))
     69:                 elsif File.directory?(item)
     70:                   queue += Dir.glob("#{item}/*", File::FNM_DOTMATCH)
     71:                   FileUtils.mkdir(File.join(destination, item))
     72:                 else
     73:                   FileUtils.ln(File.join(copy_cache, item), File.join(destination, item))
     74:                 end
     75:               end
     76:             end
     77:           else
     78:             logger.debug "getting (via #{copy_strategy}) revision #{revision} to #{destination}"
     79:             system(command)
     80:
     81:             if copy_exclude.any?
     82:               logger.debug "processing exclusions..."
     83:               if copy_exclude.any?
     84:                 copy_exclude.each do |pattern|
     85:                   delete_list = Dir.glob(File.join(destination, pattern), File::FNM_DOTMATCH)
     86:                   # avoid the /.. trap that deletes the parent directories
     87:                   delete_list.delete_if { |dir| dir =~ /\/\.\.$/ }
     88:                   FileUtils.rm_rf(delete_list.compact)
     89:                 end
     90:               end
     91:             end
     92:           end
     93:
     94:           File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }
     95:
     96:           logger.trace "compressing #{destination} to #{filename}"
     97:           Dir.chdir(tmpdir) { system(compress(File.basename(destination), File.basename(filename)).join(" ")) }
     98:
     99:           upload(filename, remote_filename)
    100:           run "cd #{configuration[:releases_path]} && #{decompress(remote_filename).join(" ")} && rm #{remote_filename}"
    101:         ensure
    102:           FileUtils.rm filename rescue nil
    103:           FileUtils.rm_rf destination rescue nil
    104:         end

deploy!()

Obtains a copy of the source code locally (via the command method), compresses it to a single file, copies that file to all target servers, and uncompresses it on each of them into the deployment directory.

[Source]

         # File lib/capistrano/recipes/deploy/strategy/copy.rb, line 46
     46:         def deploy!
     47:           if copy_cache
     48:             if File.exists?(copy_cache)
     49:               logger.debug "refreshing local cache to revision #{revision} at #{copy_cache}"
     50:               system(source.sync(revision, copy_cache))
     51:             else
     52:               logger.debug "preparing local cache at #{copy_cache}"
     53:               system(source.checkout(revision, copy_cache))
     54:             end
     55:
     56:             logger.debug "copying cache to deployment staging area #{destination}"
     57:             Dir.chdir(copy_cache) do
     58:               FileUtils.mkdir_p(destination)
     59:               queue = Dir.glob("*", File::FNM_DOTMATCH)
     60:               while queue.any?
     61:                 item = queue.shift
     62:                 name = File.basename(item)
     63:
     64:                 next if name == "." || name == ".."
     65:                 next if copy_exclude.any? { |pattern| File.fnmatch(pattern, item) }
     66:
     67:                 if File.symlink?(item)
     68:                   FileUtils.ln_s(File.readlink(File.join(copy_cache, item)), File.join(destination, item))
     69:                 elsif File.directory?(item)
     70:                   queue += Dir.glob("#{item}/*", File::FNM_DOTMATCH)
     71:                   FileUtils.mkdir(File.join(destination, item))
     72:                 else
     73:                   FileUtils.ln(File.join(copy_cache, item), File.join(destination, item))
     74:                 end
     75:               end
     76:             end
     77:           else
     78:             logger.debug "getting (via #{copy_strategy}) revision #{revision} to #{destination}"
     79:             system(command)
     80:
     81:             if copy_exclude.any?
     82:               logger.debug "processing exclusions..."
     83:               if copy_exclude.any?
     84:                 copy_exclude.each do |pattern|
     85:                   delete_list = Dir.glob(File.join(destination, pattern), File::FNM_DOTMATCH)
     86:                   # avoid the /.. trap that deletes the parent directories
     87:                   delete_list.delete_if { |dir| dir =~ /\/\.\.$/ }
     88:                   FileUtils.rm_rf(delete_list.compact)
     89:                 end
     90:               end
     91:             end
     92:           end
     93:
     94:           File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }
     95:
     96:           logger.trace "compressing #{destination} to #{filename}"
     97:           Dir.chdir(tmpdir) { system(compress(File.basename(destination), File.basename(filename)).join(" ")) }
     98:
     99:           upload(filename, remote_filename)
    100:           run "cd #{configuration[:releases_path]} && #{decompress(remote_filename).join(" ")} && rm #{remote_filename}"
    101:         ensure
    102:           FileUtils.rm filename rescue nil
    103:           FileUtils.rm_rf destination rescue nil
    104:         end

[Validate]