Class: Fulmar::Infrastructure::Service::Transfer::RsyncWithVersions

Inherits:
Base
  • Object
show all
Defined in:
lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb

Overview

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.

Constant Summary collapse

TIME_FOLDER =
'%Y-%m-%d_%H%M%S'
TIME_READABLE =
'%Y-%m-%d %H:%M:%S'
DEFAULT_CONFIG =
{
  temp_dir: 'temp',
  releases_dir: 'releases',
  shared_dir: 'shared',
  rsync: {
    exclude: nil,
    exclude_file: nil,
    chown: nil,
    chmod: nil,
    delete: true
  },
  symlinks: {},
  limit_releases: 10,
  shared: []
}

Instance Attribute Summary

Attributes inherited from Base

#config

Instance Method Summary collapse

Methods inherited from Base

#test_config

Constructor Details

#initialize(config) ⇒ RsyncWithVersions

Returns a new instance of RsyncWithVersions.



34
35
36
37
38
39
40
41
42
43
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 34

def initialize(config)
  @config = DEFAULT_CONFIG.deep_merge(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

Instance Method Details

#cleanuptrue, false

Cleans up old releases limited by :limit_releases

Returns:

  • (true, false)

    success



96
97
98
99
100
101
102
103
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 96

def cleanup
  limit = @config[:limit_releases].to_i
  return true unless limit > 0
  releases = list_releases.sort
  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

#current_releaseObject

Return the release at which the “current” symlinks points at



106
107
108
109
110
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 106

def current_release
  prepare unless @prepared
  @remote_shell.run 'readlink -f current'
  @remote_shell.last_output.first.split('/').last
end

#list_releases(plain = true) ⇒ Array

Lists the existing releases on the remote machine

Parameters:

  • plain (boolean) (defaults to: true)

    if the list should be plain directory names or more readable time strings with a star for the current release

Returns:

  • (Array)

    list of dirs or dates/times



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 82

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}/) }
  return list if plain

  current = current_release
  list.collect do |item|
    Time.strptime(item, TIME_FOLDER).strftime(TIME_READABLE) + (item == current ? ' *' : '')
  end
end

#prepareObject

Ensures all needed services are set up



46
47
48
49
50
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 46

def prepare
  super
  @remote_shell = Fulmar::Infrastructure::Service::ShellService.new @config[:remote_path], ssh_user_and_host
  @remote_shell.debug = @config[:debug]
end

#publishtrue, false

Publishes the current release (i.e. sets the ‘current’ symlink)

Returns:

  • (true, false)

    success



62
63
64
65
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 62

def publish
  prepare unless @prepared
  create_symlink
end

#release_dirString

Gets the currently generated release directory

Returns:

  • (String)

    the release directory



75
76
77
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 75

def release_dir
  @config[:releases_dir] + '/' + @release_time.strftime('%Y-%m-%d_%H%M%S')
end

#release_pathString

Gets the currently generated absolute release path

Returns:

  • (String)

    the release directory



69
70
71
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 69

def release_path
  @config[:remote_path] + '/' + release_dir
end

#revert(release) ⇒ true, false

Reverts to a given release

Returns:

  • (true, false)

    success



116
117
118
119
120
121
122
123
124
125
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 116

def revert(release)
  prepare unless @prepared

  # Convenience: Allow more readable version string from output
  if release.match(/^\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

#transfertrue, false

Copy the files via rsync to the release_path on the remote machine

Returns:

  • (true, false)

    success



54
55
56
57
58
# File 'lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb', line 54

def transfer
  prepare unless @prepared

  create_paths && @local_shell.run(rsync_command) && copy_temp_to_release && add_shared
end