Class: Fulmar::Infrastructure::Model::Transfer::RsyncWithVersions

Inherits:
Base
  • Object
show all
Defined in:
lib/fulmar/infrastructure/model/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'.freeze
TIME_READABLE =
'%Y-%m-%d %H:%M:%S'.freeze
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: 5,
  version_name: 'time',
  shared: []
}.freeze

Instance Attribute Summary

Attributes inherited from Base

#config

Instance Method Summary collapse

Methods inherited from Base

config_hash, #test_config

Constructor Details

#initialize(config) ⇒ RsyncWithVersions

Returns a new instance of RsyncWithVersions.



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

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
end

Instance Method Details

#cleanuptrue, false

Cleans up old releases limited by :limit_releases

Returns:

  • (true, false)

    success



110
111
112
113
114
115
116
117
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 110

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

#current_releaseObject

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



120
121
122
123
124
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 120

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



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 92

def list_releases(plain = true)
  prepare unless @prepared
  @remote_shell.run "ls -1tr '#{@config[:releases_dir]}'"
  list = @remote_shell.last_output
  return list if plain

  current = current_release
  list.collect do |item|
    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

#prepareObject

Ensures all needed services are set up



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 47

def prepare
  super
  @remote_shell = Fulmar::Shell.new @config[:remote_path], @config.ssh_user_and_host
  @remote_shell.debug = @config[:debug]

  if @config[:version_name] == 'time'
    @config[:version_name] = Time.now.strftime(TIME_FOLDER)
  elsif /^[A-Z][A-Z0-9\-_]+$/ =~ @config[:version_name]
    @config[:version_name] = ENV[@config[:version_name]].split('/').last
  end
end

#publishtrue, false

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

Returns:

  • (true, false)

    success



72
73
74
75
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 72

def publish
  prepare unless @prepared
  create_symlink
end

#release_dirString

Gets the currently generated release directory

Returns:

  • (String)

    the release directory



85
86
87
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 85

def release_dir
  @config[:releases_dir] + '/' + @config[:version_name]
end

#release_pathString

Gets the currently generated absolute release path

Returns:

  • (String)

    the release directory



79
80
81
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 79

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

#revert(release = last_release) ⇒ true, false

Reverts to a given release

Returns:

  • (true, false)

    success



130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 130

def revert(release = last_release)
  prepare unless @prepared

  return false if release.nil?

  # Convenience: Allow more readable version string from output
  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

#transfertrue, false

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

Returns:

  • (true, false)

    success



61
62
63
64
65
66
67
68
# File 'lib/fulmar/infrastructure/model/transfer/rsync_with_versions.rb', line 61

def transfer
  prepare unless @prepared

  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