ferry 1.3.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,69 @@
1
+ require 'set'
2
+ require 'ferry/configuration'
3
+ require 'ferry/configuration/filter'
4
+
5
+ module Ferry
6
+ class Configuration
7
+ class Servers
8
+ include Enumerable
9
+
10
+ def add_host(host, properties={})
11
+ new_host = Server[host]
12
+ if server = servers.find { |s| s.matches? new_host }
13
+ server.user = new_host.user if new_host.user
14
+ server.port = new_host.port if new_host.port
15
+ server.with(properties)
16
+ else
17
+ servers << new_host.with(properties)
18
+ end
19
+ end
20
+
21
+ def add_role(role, hosts, options={})
22
+ options_deepcopy = Marshal.dump(options.merge(roles: role))
23
+ Array(hosts).each { |host| add_host(host, Marshal.load(options_deepcopy)) }
24
+ end
25
+
26
+ def roles_for(names)
27
+ options = extract_options(names)
28
+ s = Filter.new(:role, names).filter(servers)
29
+ s.select { |server| server.select?(options) }
30
+ end
31
+
32
+ def role_properties_for(rolenames)
33
+ roles = rolenames.to_set
34
+ rps = Set.new unless block_given?
35
+ roles_for(rolenames).each do |host|
36
+ host.roles.intersection(roles).each do |role|
37
+ [host.properties.fetch(role)].flatten(1).each do |props|
38
+ if block_given?
39
+ yield host, role, props
40
+ else
41
+ rps << (props || {}).merge( role: role, hostname: host.hostname )
42
+ end
43
+ end
44
+ end
45
+ end
46
+ block_given? ? nil: rps
47
+ end
48
+
49
+ def fetch_primary(role)
50
+ hosts = roles_for([role])
51
+ hosts.find(&:primary) || hosts.first
52
+ end
53
+
54
+ def each
55
+ servers.each { |server| yield server }
56
+ end
57
+
58
+ private
59
+
60
+ def servers
61
+ @servers ||= []
62
+ end
63
+
64
+ def extract_options(array)
65
+ array.last.is_a?(::Hash) ? array.pop : {}
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ # default options for user to replace in the deploy_ferry.rb
2
+ # still not sure what we can put here ...
3
+ # see deploy_ferry.rb.erb for ideas
@@ -0,0 +1,3 @@
1
+ require 'ferry/framework'
2
+
3
+ load File.expand_path("../tasks/deploy.rake", __FILE__)
@@ -0,0 +1,2 @@
1
+ dotfile = Pathname.new(File.join(Dir.home, '.ferryfile'))
2
+ load dotfile if dotfile.file?
@@ -0,0 +1,64 @@
1
+ require 'etc'
2
+ require 'ferry/dsl/task_enhancements'
3
+ require 'ferry/dsl/paths'
4
+ require 'ferry/dsl/stages'
5
+ require 'ferry/dsl/env'
6
+ require 'ferry/configuration/filter'
7
+
8
+ module Ferry
9
+ module DSL
10
+ include TaskEnhancements
11
+ include Env
12
+ include Paths
13
+ include Stages
14
+
15
+ def invoke(task, *args)
16
+ Rake::Task[task].invoke(*args)
17
+ end
18
+
19
+ def t(key, options={})
20
+ I18n.t(key, options.merge(scope: :ferry))
21
+ end
22
+
23
+ def scm
24
+ fetch(:scm)
25
+ end
26
+
27
+ def sudo(*args)
28
+ execute :sudo, *args
29
+ end
30
+
31
+ def revision_log_message
32
+ fetch(:revision_log_message,
33
+ t(:revision_log_message,
34
+ branch: fetch(:branch),
35
+ user: local_user,
36
+ sha: fetch(:current_revision),
37
+ release: fetch(:release_timestamp))
38
+ )
39
+ end
40
+
41
+ def rollback_log_message
42
+ t(:rollback_log_message, user: local_user, release: fetch(:rollback_timestamp))
43
+ end
44
+
45
+ def local_user
46
+ fetch(:local_user)
47
+ end
48
+
49
+ def lock(locked_version)
50
+ VersionValidator.new(locked_version).verify
51
+ end
52
+
53
+ def on(hosts, options={}, &block)
54
+ subset_copy = Marshal.dump(Configuration.env.filter(hosts))
55
+ SSHKit::Coordinator.new(Marshal.load(subset_copy)).each(options, &block)
56
+ end
57
+
58
+ def run_locally(&block)
59
+ SSHKit::Backend::Local.new(&block).run
60
+ end
61
+
62
+ end
63
+ end
64
+ self.extend Ferry::DSL
@@ -0,0 +1,81 @@
1
+ module Ferry
2
+ module DSL
3
+ module Env
4
+
5
+ def configure_backend
6
+ env.configure_backend
7
+ end
8
+
9
+ def fetch(key, default=nil, &block)
10
+ env.fetch(key, default, &block)
11
+ end
12
+
13
+ def any?(key)
14
+ value = fetch(key)
15
+ if value && value.respond_to?(:any?)
16
+ value.any?
17
+ else
18
+ !fetch(key).nil?
19
+ end
20
+ end
21
+
22
+ def set(key, value)
23
+ env.set(key, value)
24
+ end
25
+
26
+ def set_if_empty(key, value)
27
+ env.set_if_empty(key, value)
28
+ end
29
+
30
+ def delete(key)
31
+ env.delete(key)
32
+ end
33
+
34
+ def ask(key, value, options={})
35
+ env.ask(key, value, options)
36
+ end
37
+
38
+ def role(name, servers, options={})
39
+ env.role(name, servers, options)
40
+ end
41
+
42
+ def server(name, properties={})
43
+ env.server(name, properties)
44
+ end
45
+
46
+ def roles(*names)
47
+ env.roles_for(names.flatten)
48
+ end
49
+
50
+ def role_properties(*names, &block)
51
+ env.role_properties_for(names, &block)
52
+ end
53
+
54
+ def release_roles(*names)
55
+ if names.last.is_a? Hash
56
+ names.last.merge!({ :exclude => :no_release })
57
+ else
58
+ names << { exclude: :no_release }
59
+ end
60
+ roles(*names)
61
+ end
62
+
63
+ def primary(role)
64
+ env.primary(role)
65
+ end
66
+
67
+ def env
68
+ Configuration.env
69
+ end
70
+
71
+ def release_timestamp
72
+ env.timestamp.strftime("%Y%m%d%H%M%S")
73
+ end
74
+
75
+ def asset_timestamp
76
+ env.timestamp.strftime("%Y%m%d%H%M.%S")
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,103 @@
1
+ require 'pathname'
2
+ module Ferry
3
+ module DSL
4
+ module Paths
5
+
6
+ def deploy_to
7
+ fetch(:deploy_to)
8
+ end
9
+
10
+ def deploy_path
11
+ Pathname.new(deploy_to)
12
+ end
13
+
14
+ def current_path
15
+ deploy_path.join('current')
16
+ end
17
+
18
+ def releases_path
19
+ deploy_path.join('releases')
20
+ end
21
+
22
+ def release_path
23
+ fetch(:release_path, current_path)
24
+ end
25
+
26
+ def set_release_path(timestamp=now)
27
+ set(:release_timestamp, timestamp)
28
+ set(:release_path, releases_path.join(timestamp))
29
+ end
30
+
31
+ def stage_config_path
32
+ Pathname.new fetch(:stage_config_path, 'config/deploy')
33
+ end
34
+
35
+ def deploy_config_path
36
+ Pathname.new fetch(:deploy_config_path, 'config/deploy.rb')
37
+ end
38
+
39
+ def repo_url
40
+ require 'cgi'
41
+ require 'uri'
42
+ if fetch(:git_http_username) and fetch(:git_http_password)
43
+ URI.parse(fetch(:repo_url)).tap do |repo_uri|
44
+ repo_uri.user = fetch(:git_http_username)
45
+ repo_uri.password = CGI.escape(fetch(:git_http_password))
46
+ end.to_s
47
+ elsif fetch(:git_http_username)
48
+ URI.parse(fetch(:repo_url)).tap do |repo_uri|
49
+ repo_uri.user = fetch(:git_http_username)
50
+ end.to_s
51
+ else
52
+ fetch(:repo_url)
53
+ end
54
+ end
55
+
56
+ def repo_path
57
+ Pathname.new(fetch(:repo_path, ->(){deploy_path.join('repo')}))
58
+ end
59
+
60
+ def shared_path
61
+ deploy_path.join('shared')
62
+ end
63
+
64
+ def revision_log
65
+ deploy_path.join('revisions.log')
66
+ end
67
+
68
+ def now
69
+ env.timestamp.strftime("%Y%m%d%H%M%S")
70
+ end
71
+
72
+ def asset_timestamp
73
+ env.timestamp.strftime("%Y%m%d%H%M.%S")
74
+ end
75
+
76
+ def linked_dirs(parent)
77
+ paths = fetch(:linked_dirs)
78
+ join_paths(parent, paths)
79
+ end
80
+
81
+ def linked_files(parent)
82
+ paths = fetch(:linked_files)
83
+ join_paths(parent, paths)
84
+ end
85
+
86
+ def linked_file_dirs(parent)
87
+ map_dirnames(linked_files(parent))
88
+ end
89
+
90
+ def linked_dir_parents(parent)
91
+ map_dirnames(linked_dirs(parent))
92
+ end
93
+
94
+ def join_paths(parent, paths)
95
+ paths.map { |path| parent.join(path) }
96
+ end
97
+
98
+ def map_dirnames(paths)
99
+ paths.map { |path| path.dirname }
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,19 @@
1
+ module Ferry
2
+ module DSL
3
+ module Stages
4
+
5
+ def stages
6
+ Dir[stage_definitions].map { |f| File.basename(f, '.rb') }
7
+ end
8
+
9
+ def stage_definitions
10
+ stage_config_path.join('*.rb')
11
+ end
12
+
13
+ def stage_set?
14
+ !!fetch(:stage, false)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,65 @@
1
+ require 'ferry/upload_task'
2
+
3
+ module Ferry
4
+ module TaskEnhancements
5
+ def before(task, prerequisite, *args, &block)
6
+ prerequisite = Rake::Task.define_task(prerequisite, *args, &block) if block_given?
7
+ Rake::Task[task].enhance [prerequisite]
8
+ end
9
+
10
+ def after(task, post_task, *args, &block)
11
+ Rake::Task.define_task(post_task, *args, &block) if block_given?
12
+ Rake::Task[task].enhance do
13
+ Rake::Task[post_task].invoke
14
+ end
15
+ end
16
+
17
+ def remote_file(task)
18
+ target_roles = task.delete(:roles) { :all }
19
+ define_remote_file_task(task, target_roles)
20
+ end
21
+
22
+ def define_remote_file_task(task, target_roles)
23
+ Ferry::UploadTask.define_task(task) do |t|
24
+ prerequisite_file = t.prerequisites.first
25
+ file = shared_path.join(t.name)
26
+
27
+ on roles(target_roles) do
28
+ unless test "[ -f #{file.to_s.shellescape} ]"
29
+ info "Uploading #{prerequisite_file} to #{file}"
30
+ upload! File.open(prerequisite_file), file
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+
37
+ def ensure_stage
38
+ Rake::Task.define_task(:ensure_stage) do
39
+ unless stage_set?
40
+ puts t(:stage_not_set)
41
+ exit 1
42
+ end
43
+ end
44
+ end
45
+
46
+ def tasks_without_stage_dependency
47
+ stages + default_tasks
48
+ end
49
+
50
+ def default_tasks
51
+ %w{install}
52
+ end
53
+
54
+ def exit_deploy_because_of_exception(ex)
55
+ warn t(:deploy_failed, ex: ex.message)
56
+ invoke 'deploy:failed'
57
+ exit(false)
58
+ end
59
+
60
+ def deploying?
61
+ fetch(:deploying, false)
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,2 @@
1
+ load File.expand_path("../tasks/framework.rake", __FILE__)
2
+ require 'ferry/install'
@@ -0,0 +1,18 @@
1
+ require 'i18n'
2
+
3
+ en = {
4
+ starting: 'Starting',
5
+ installing: 'Installing',
6
+ set_sail: 'Set Sail!',
7
+ moving: 'Moving',
8
+ completed: 'Completed'
9
+ },
10
+ error: 'Some error'
11
+ }
12
+ }
13
+
14
+ I18n.backend.store_translations(:en, { ferry: en })
15
+
16
+ if I18n.respond_to?(:enforce_available_locales=)
17
+ I18n.enforce_available_locales = true
18
+ end
@@ -0,0 +1 @@
1
+ load File.expand_path(File.join(File.dirname(__FILE__),'tasks/install.rake'))