lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb in fulmar-2.1.2 vs lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb in fulmar-2.2.0

- old
+ new

@@ -10,12 +10,12 @@ # Provides syncing with versioning on the server # # Every deployment results in a new directory in the releases directory with the deployment time as # the folder name. A symlink 'current' points to this new directory after publish() is called. class RsyncWithVersions < Base - TIME_FOLDER = '%Y-%m-%d_%H%M%S' - TIME_READABLE = '%Y-%m-%d %H:%M:%S' + TIME_FOLDER = '%Y-%m-%d_%H%M%S'.freeze + TIME_READABLE = '%Y-%m-%d %H:%M:%S'.freeze DEFAULT_CONFIG = { temp_dir: 'temp', releases_dir: 'releases', shared_dir: 'shared', @@ -26,42 +26,45 @@ chmod: nil, delete: true }, symlinks: {}, limit_releases: 5, + version_name: Time.now.strftime('%Y-%m-%d_%H%M%S'), shared: [] - } + }.freeze # @param [Fulmar::Domain::Service::ConfigurationService] config def initialize(config) @config = config @config.merge(DEFAULT_CONFIG) super(@config) if @config[:rsync][:exclude_file].blank? && File.exist?(@config[:local_path] + '/.rsyncignore') @config[:rsync][:exclude_file] = @config[:local_path] + '/.rsyncignore' end - - @release_time = Time.now end # Ensures all needed services are set up def prepare super @remote_shell = Fulmar::Shell.new @config[:remote_path], @config.ssh_user_and_host @remote_shell.debug = @config[:debug] + + if /^[A-Z][A-Z0-9\-_]+$/ =~ @config[:version_name] + @config[:version_name] = ENV[@config[:version_name]].split('/').last + end end # Copy the files via rsync to the release_path on the remote machine # @return [true, false] success def transfer prepare unless @prepared - fail 'Deployment failed when trying to prepare remote directories for sync.' unless create_paths - fail 'Deployment failed. Cannot sync files.' unless @local_shell.run(rsync_command) - fail 'Deployment failed when trying to move file from temporary upload dir.' unless copy_temp_to_release - fail 'Deployment failed when creating symlinks for shared folders' unless add_shared + raise 'Deployment failed when trying to prepare remote directories for sync.' unless create_paths + raise 'Deployment failed. Cannot sync files.' unless @local_shell.run(rsync_command) + raise 'Deployment failed when trying to move file from temporary upload dir.' unless copy_temp_to_release + raise 'Deployment failed when creating symlinks for shared folders' unless add_shared end # Publishes the current release (i.e. sets the 'current' symlink) # @return [true, false] success def publish @@ -76,34 +79,38 @@ end # Gets the currently generated release directory # @return [String] the release directory def release_dir - @config[:releases_dir] + '/' + @release_time.strftime('%Y-%m-%d_%H%M%S') + @config[:releases_dir] + '/' + @config[:version_name] end # Lists the existing releases on the remote machine # @param plain [boolean] if the list should be plain directory names or more readable time strings with a star for the current release # @return [Array] list of dirs or dates/times def list_releases(plain = true) prepare unless @prepared - @remote_shell.run "ls -1 '#{@config[:releases_dir]}'" - list = @remote_shell.last_output.select { |dir| dir.match(/^\d{4}-\d{2}-\d{2}_\d{6}/) } + @remote_shell.run "ls -1tr '#{@config[:releases_dir]}'" + list = @remote_shell.last_output return list if plain current = current_release list.collect do |item| - Time.strptime(item, TIME_FOLDER).strftime(TIME_READABLE) + (item == current ? ' *' : '') + if item =~ /^\d{4}-\d{2}-\d{2}_\d{6}/ + Time.strptime(item, TIME_FOLDER).strftime(TIME_READABLE) + (item == current ? ' *' : '') + else + item + (item == current ? ' *' : '') + end end end # Cleans up old releases limited by :limit_releases # @return [true, false] success def cleanup limit = @config[:limit_releases].to_i return true unless limit > 0 - releases = list_releases.sort + releases = list_releases return true if releases.length <= limit obsolete_dirs = releases[0, releases.length - limit].collect { |dir| "\"#{@config[:releases_dir]}/#{dir}\"" } @remote_shell.run "rm -fr #{obsolete_dirs.join(' ')}" end @@ -122,11 +129,11 @@ prepare unless @prepared return false if release.nil? # Convenience: Allow more readable version string from output - if release.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/) + if release =~ /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/ release = Time.strptime(item, TIME_READABLE).strftime(TIME_FOLDER) end create_symlink release end @@ -134,19 +141,19 @@ protected def last_release list = list_releases current = current_release - current_index = list.index(current) - (current_index.nil? || current_index == 0) ? nil : list[current_index - 1] + current_index = list.index(current).to_i + current_index.zero? ? nil : list[current_index - 1] end # Creates all necessary paths on the remote machine # @return [true, false] success def create_paths paths = [@config[:releases_dir], @config[:temp_dir], @config[:shared_dir]] - @remote_shell.run paths.collect { |path| "mkdir -p '#{@config[:remote_path]}/#{path}'" } + @remote_shell.run(paths.collect { |path| "mkdir -p '#{@config[:remote_path]}/#{path}'" }) end def rsync_excludes return nil unless @config[:rsync][:exclude] excludes = [*@config[:rsync][:exclude]] @@ -154,10 +161,10 @@ end # Builds the rsync command # @return [String] the command def rsync_command - options = %w(-rl --delete-excluded) + options = %w[-rl --delete-excluded] options << rsync_excludes if rsync_excludes options << "--exclude-from='#{@config[:rsync][:exclude_file]}'" if @config[:rsync][:exclude_file] options << "--chown='#{@config[:rsync][:chown]}'" if @config[:rsync][:chown] options << "--chmod='#{@config[:rsync][:chmod]}'" if @config[:rsync][:chmod] options << '--delete' if @config[:rsync][:delete]