fulmar 1.0.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46c85744adefad501d5efd90fef1a22ebf0f8f51
4
- data.tar.gz: d6dfa27af53d6ba87f51699583d2ab0edc55cedd
3
+ metadata.gz: ec0fe71a95742d097b3d61053620fee7453fcd7f
4
+ data.tar.gz: d92d58a45c299f073afb02ea32e26fe2344b3d68
5
5
  SHA512:
6
- metadata.gz: 5c5e48948f29b756590a48c0ddae233d08b21787f4d588604abce5a0da6d6547b889ea2b484c4136ff8798d7b80939e0d9eb0822a98ffd7ed99c1652341c6af0
7
- data.tar.gz: 194914af1388156b2f492c90027885e99717296751e878e5f72d52f44cc0660d59b96785013a0b45ee5ba183f58dceb9a5dea1a5367ddf3c4b1ea3be9b6b57e6
6
+ metadata.gz: 7f8ebdc7e5247a90f35db2c30bfbef6630679f05b25b689325e2d984f3d23032df58e1e69d37e9981dac0461b28e2ed972badecc351965d11bdb8c35cb4a590e
7
+ data.tar.gz: 777be47a8bb21a2343fd5d8934464f3000133f8b287206a6afa3eee9d4cd8de90c99fbfca80524d189f038304c5030937c63322b9f6f538b93982bf63cfff347
data/fulmar.gemspec CHANGED
@@ -21,8 +21,9 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency 'bundler', '~> 1.7'
22
22
 
23
23
  spec.add_runtime_dependency 'rake', '~>10'
24
- spec.add_runtime_dependency 'git', '~>1.2'
24
+ spec.add_runtime_dependency 'rugged', '~>0'
25
25
  spec.add_runtime_dependency 'mysql2', '~>0.3'
26
26
  spec.add_runtime_dependency 'fulmar-shell', '~>1', '>=1.4.0'
27
27
  spec.add_runtime_dependency 'ruby_wings', '~>0.1', '>=0.1.0'
28
+ spec.add_runtime_dependency 'colorize', '~>0'
28
29
  end
@@ -30,7 +30,7 @@ module Fulmar
30
30
  end
31
31
 
32
32
  def wrap_environment
33
- Proc.new do
33
+ proc do
34
34
  configuration = Fulmar::Domain::Service::ConfigurationService.instance
35
35
  environment = configuration.environment
36
36
  target = configuration.target
@@ -11,7 +11,8 @@ module Fulmar
11
11
 
12
12
  def render
13
13
  return unless @config[:config_templates]
14
- @config[:config_templates].each do |template|
14
+ @config[:config_templates].each do |template_file|
15
+ template = "#{@config[:local_path]}/#{template_file}"
15
16
  fail "Template filenames must end in .erb - '#{template}' does not" unless template[-4, 4] == '.erb'
16
17
  fail "Cannot render missing config file '#{template}'" unless File.exist? template
17
18
 
@@ -33,7 +33,7 @@ module Fulmar
33
33
  else
34
34
  fail 'Environment or target not set. Please set both variables via configuration.environment = \'xxx\' / '\
35
35
  'configuration.target = \'yyy\''
36
- end
36
+ end
37
37
  end
38
38
 
39
39
  def to_hash
@@ -61,10 +61,13 @@ module Fulmar
61
61
  end
62
62
 
63
63
  def ready?
64
- !@environment.nil? && !@target.nil?
64
+ return false if @environment.nil? || @target.nil?
65
+ fail 'Environment is invalid' if configuration[:environments][@environment].nil?
66
+ fail 'Target is invalid' if configuration[:environments][@environment][@target].nil?
67
+ true
65
68
  end
66
69
 
67
- def has_feature?(feature)
70
+ def feature?(feature)
68
71
  return configuration[:features][feature] unless configuration[:features][feature].nil?
69
72
  case feature
70
73
  when :database
@@ -84,7 +87,7 @@ module Fulmar
84
87
 
85
88
  def any?
86
89
  if block_given?
87
- each{ |_env, _target, data| return true if yield(data) }
90
+ each { |_env, _target, data| return true if yield(data) }
88
91
  false
89
92
  else
90
93
  configuration[:environments].any?
@@ -96,9 +99,8 @@ module Fulmar
96
99
  # Hashes are merged.
97
100
  # @param [Hash] other
98
101
  def merge(other)
99
- if @environment && @target
100
- configuration[:environments][@environment][@target] = other.deep_merge(configuration[:environments][@environment][@target])
101
- end
102
+ return unless @environment && @target
103
+ configuration[:environments][@environment][@target] = other.deep_merge(configuration[:environments][@environment][@target])
102
104
  end
103
105
 
104
106
  def config_files
@@ -121,25 +123,25 @@ module Fulmar
121
123
  # Fills a target with all globally set variables so all necessary information
122
124
  # is found within each target
123
125
  def fill_target(env, target)
124
- @config[:environments][env][target] = @config[:environments][:all].deep_merge(@config[:environments][env][target])
125
-
126
- unless @config[:environments][env][target][:host].blank?
127
- host = @config[:environments][env][target][:host].to_sym
128
- if @config[:hosts] && @config[:hosts][host]
129
- @config[:hosts][host].each do
130
- @config[:environments][env][target] = @config[:hosts][host].deep_merge(@config[:environments][env][target])
131
- end
132
- else
133
- fail "Host #{host} is not configured."
126
+ @config[:environments][env][target] = @config[:environments][:all].deep_merge(@config[:environments][env][target]) if @config[:environments][:all]
127
+
128
+ return if @config[:environments][env][target][:host].blank?
129
+
130
+ host = @config[:environments][env][target][:host].to_sym
131
+ if @config[:hosts] && @config[:hosts][host]
132
+ @config[:hosts][host].each do
133
+ @config[:environments][env][target] = @config[:hosts][host].deep_merge(@config[:environments][env][target])
134
134
  end
135
+ else
136
+ fail "Host #{host} is not configured."
135
137
  end
136
138
  end
137
139
 
138
140
  # Loads the configuration from the YAML file and populates all targets
139
141
  def load_configuration
140
- @config = { environments: {}, features: {} }
142
+ @config = { environments: {}, features: {}, hosts: {} }
141
143
  config_files.each do |config_file|
142
- @config = @config.deep_merge(YAML.load_file(config_file).symbolize)
144
+ @config = @config.deep_merge((YAML.load_file(config_file) || {}).symbolize)
143
145
  end
144
146
 
145
147
  # Iterate over all environments and targets to prepare them
@@ -155,9 +157,8 @@ module Fulmar
155
157
  end
156
158
 
157
159
  def check_path(env, target)
158
- unless @config[:environments][env][target][:local_path].blank?
159
- @config[:environments][env][target][:local_path] = File.expand_path(@config[:environments][env][target][:local_path])
160
- end
160
+ return if @config[:environments][env][target][:local_path].blank?
161
+ @config[:environments][env][target][:local_path] = File.expand_path(@config[:environments][env][target][:local_path])
161
162
  end
162
163
  end
163
164
  end
@@ -1,11 +1,11 @@
1
1
  include Fulmar::Domain::Service::Helper::CommonHelper
2
2
 
3
- if configuration.has_feature? :database
3
+ if configuration.feature? :database
4
4
  require 'fulmar/service/helper/database_helper'
5
5
  include Fulmar::Domain::Service::Helper::DatabaseHelper
6
6
  end
7
7
 
8
- if configuration.has_feature? :flow
8
+ if configuration.feature? :flow
9
9
  require 'fulmar/service/helper/flow_helper'
10
10
  include Fulmar::Domain::Service::Helper::FlowHelper
11
- end
11
+ end
@@ -39,8 +39,6 @@ end
39
39
 
40
40
  if db_configs.any?
41
41
  namespace :database do
42
- if db_configs.count > 1
43
- create_update_tasks(db_configs)
44
- end
42
+ create_update_tasks(db_configs) if db_configs.count > 1
45
43
  end
46
44
  end
@@ -1,12 +1,7 @@
1
1
  include Fulmar::Domain::Service::Helper::CommonHelper
2
2
 
3
3
  namespace :versions do
4
-
5
4
  @versioned_servers = {}
6
- configuration.each do |env, target, data|
7
-
8
- end
9
-
10
5
 
11
6
  full_configuration[:environments].each_pair do |env, targets|
12
7
  next if env == :all
@@ -23,7 +18,7 @@ namespace :versions do
23
18
  task env do
24
19
  configuration.environment = env.split(':').first
25
20
  configuration.target = env.split(':').last
26
- file_sync.list_releases(false).each{|item| puts item}
21
+ file_sync.list_releases(false).each { |item| puts item }
27
22
  end
28
23
  end
29
24
  end
@@ -38,7 +33,5 @@ namespace :versions do
38
33
  end
39
34
  end
40
35
  end
41
-
42
-
43
36
  end
44
37
  end
@@ -3,12 +3,13 @@ module Fulmar
3
3
  module Service
4
4
  # Provides access to composer
5
5
  class ComposerService
6
- def initialize(custom_path = '/usr/bin/env composer')
6
+ def initialize(shell, custom_path = '/usr/bin/env composer')
7
+ @local_shell = shell
7
8
  @path = custom_path
8
9
  end
9
10
 
10
11
  def execute(command, arguments = [])
11
- system "#{@path} #{command} #{arguments.join(' ')} > /dev/null"
12
+ @local_shell.run "#{@path} #{command} #{arguments.join(' ')} > /dev/null"
12
13
  end
13
14
  end
14
15
  end
@@ -8,7 +8,8 @@ module Fulmar
8
8
  # Provides basic methods common to all database services
9
9
  class DatabaseService
10
10
  attr_accessor :client
11
- attr_reader :shell
11
+ attr_reader :shell, :connected
12
+ alias_method :connected?, :connected
12
13
 
13
14
  DEFAULT_CONFIG = {
14
15
  maria: {
@@ -16,7 +17,7 @@ module Fulmar
16
17
  port: 3306,
17
18
  user: 'root',
18
19
  password: '',
19
- encoding: 'utf8',
20
+ encoding: 'utf8'
20
21
  }
21
22
  }
22
23
 
@@ -39,13 +40,7 @@ module Fulmar
39
40
 
40
41
  # Wait max 3 seconds for the tunnel to establish
41
42
  4.times do |i|
42
- begin
43
- @client = Mysql2::Client.new options
44
- break
45
- rescue Mysql2::Error => e
46
- sleep 1 if i < 3
47
- fail e.message if i == 3
48
- end
43
+ break if try_connect(options, i)
49
44
  end
50
45
 
51
46
  @connected = true
@@ -57,10 +52,6 @@ module Fulmar
57
52
  @tunnel.close if @tunnel # using the variable directly avoids creating a tunnel instance when closing the database connection
58
53
  end
59
54
 
60
- def connected?
61
- @connected
62
- end
63
-
64
55
  def local?
65
56
  @config[:hostname] == 'localhost'
66
57
  end
@@ -109,6 +100,13 @@ module Fulmar
109
100
 
110
101
  protected
111
102
 
103
+ def try_connect(options, i)
104
+ @client = Mysql2::Client.new options
105
+ rescue Mysql2::Error => e
106
+ sleep 1 if i < 3
107
+ raise e.message if i == 3
108
+ end
109
+
112
110
  # Test configuration
113
111
  def config_test
114
112
  fail 'Configuration option "database" missing.' unless @config[:maria][:database]
@@ -132,19 +130,17 @@ module Fulmar
132
130
  # Compiles a mysql config hash from valid options of the fulmar config
133
131
  def compile_options
134
132
  possible_options = [:host, :username, :password, :port, :encoding, :socket, :read_timeout, :write_timeout,
135
- :connect_timeout, :reconnect, :local_infile, :secure_auth, :default_file, :default_group,
136
- :init_command
137
- ]
138
- options = {}
139
- options[:host] = '127.0.0.1'
140
- options[:username] = @config[:maria][:user]
133
+ :connect_timeout, :reconnect, :local_infile, :secure_auth, :default_file, :default_group,
134
+ :init_command
135
+ ]
136
+ options = { host: '127.0.0.1', username: @config[:maria][:user] }
137
+
141
138
  possible_options.each do |option|
142
139
  options[option] = @config[:maria][option] unless @config[:maria][option].nil?
143
140
  end
144
141
 
145
142
  options
146
143
  end
147
-
148
144
  end
149
145
  end
150
146
  end
@@ -1,4 +1,4 @@
1
- require 'git'
1
+ require 'rugged'
2
2
 
3
3
  module Fulmar
4
4
  module Infrastructure
@@ -29,29 +29,27 @@ module Fulmar
29
29
  end
30
30
  end
31
31
 
32
- @git = Git.open(@config[:local_path]) # :log => Logger.new(STDOUT)
32
+ @git = Rugged::Repository.new(@config[:local_path]) # :log => Logger.new(STDOUT)
33
33
  end
34
34
 
35
35
  def branches
36
- @git.branches
36
+ @git.branches.collect(:name)
37
37
  end
38
38
 
39
39
  def feature_branches
40
- @git.branches.collect { |b| b.full }.select { |name| name.match(/^feature_/) }.sort
40
+ branches.select { |name| name.match(/^feature_/) }.sort
41
41
  end
42
42
 
43
43
  def preview_branches
44
- @git.branches.collect { |b| b.full }.select { |name| name.match(/^preview_/) }.sort
44
+ branches.select { |name| name.match(/^preview_/) }.sort
45
45
  end
46
46
 
47
47
  def checkout(branch_name = derive_branch_name)
48
- branches = @git.branches.local.find(branch_name)
49
- if branches.any?
48
+ if branches.include?(branch_name)
50
49
  @git.checkout(branches.first)
51
50
  else
52
- branches = @git.branches.remote.find(branch_name)
51
+ branches = @git.branches.select { |b| b.name.match(/\/#{branch_name}$/) }
53
52
  fail "Cannot find a valid branch, last search was for #{branch_name}" unless branches.any?
54
- @git.branch(branches.first)
55
53
  @git.checkout(branches.first)
56
54
  end
57
55
  end
@@ -60,7 +58,6 @@ module Fulmar
60
58
  def derive_branch_name
61
59
  @config[:git][:branch] == 'preview' ? preview_branches.last : @config[:git][:branch]
62
60
  end
63
-
64
61
  end
65
62
  end
66
63
  end
@@ -33,14 +33,8 @@ module Fulmar
33
33
  @local_shell.run rsync_command
34
34
  end
35
35
 
36
+ # Build the rsync command from the given options
36
37
  def rsync_command
37
- options = ['-rl']
38
- options << "--exclude='#{@config[:rsync][:exclude]}'" if @config[:rsync][:exclude]
39
- options << "--exclude-from='#{@config[:rsync][:exclude_file]}'" if @config[:rsync][:exclude_file]
40
- options << "--chown='#{@config[:rsync][:chown]}'" if @config[:rsync][:chown]
41
- options << "--chmod='#{@config[:rsync][:chmod]}'" if @config[:rsync][:chmod]
42
- options << '--delete' if @config[:rsync][:delete]
43
-
44
38
  if @config[:rsync][:direction] == 'up'
45
39
  from = @config[:local_path]
46
40
  to = ssh_user_and_host + ':' + @config[:remote_path]
@@ -49,7 +43,20 @@ module Fulmar
49
43
  to = @config[:local_path]
50
44
  end
51
45
 
52
- "rsync #{options.join(' ')} '#{from}/' '#{to}'"
46
+ "rsync #{rsync_command_options.join(' ')} '#{from}/' '#{to}'"
47
+ end
48
+
49
+ protected
50
+
51
+ # Assembles all rsync command line parameters from the configuration options
52
+ def rsync_command_options
53
+ options = ['-rl']
54
+ options << "--exclude='#{@config[:rsync][:exclude]}'" if @config[:rsync][:exclude]
55
+ options << "--exclude-from='#{@config[:rsync][:exclude_file]}'" if @config[:rsync][:exclude_file]
56
+ options << "--chown='#{@config[:rsync][:chown]}'" if @config[:rsync][:chown]
57
+ options << "--chmod='#{@config[:rsync][:chmod]}'" if @config[:rsync][:chmod]
58
+ options << '--delete' if @config[:rsync][:delete]
59
+ options
53
60
  end
54
61
  end
55
62
  end
@@ -3,6 +3,7 @@ require 'socket'
3
3
  module Fulmar
4
4
  module Infrastructure
5
5
  module Service
6
+ # Opens an ssh tunnel to a remote host so other services can access mysql for example
6
7
  class TunnelService
7
8
  attr_reader :host, :remote_port, :local_port
8
9
 
@@ -31,20 +32,18 @@ module Fulmar
31
32
  end
32
33
 
33
34
  def free_port
34
- port = 60000
35
- begin
36
- 1000.times do
35
+ (60_000..61_000).each do |port|
36
+ begin
37
37
  socket = TCPSocket.new('localhost', port)
38
38
  socket.close
39
- port += 1
39
+ rescue Errno::ECONNREFUSED
40
+ return port
40
41
  end
41
- rescue Errno::ECONNREFUSED
42
- return port
43
42
  end
43
+
44
44
  fail 'Cannot find an open local port'
45
- 0
46
45
  end
47
46
  end
48
47
  end
49
48
  end
50
- end
49
+ end
@@ -1,4 +1,5 @@
1
1
  require 'fulmar/domain/service/configuration_service'
2
+ require 'colorize'
2
3
 
3
4
  module Fulmar
4
5
  module Domain
@@ -17,7 +18,7 @@ module Fulmar
17
18
  end
18
19
 
19
20
  def composer(command, arguments = [])
20
- (storage['composer'] ||= Fulmar::Infrastructure::Service::ComposerService.new).execute(command, arguments)
21
+ (storage['composer'] ||= Fulmar::Infrastructure::Service::ComposerService.new(local_shell)).execute(command, arguments)
21
22
  end
22
23
 
23
24
  def local_shell
@@ -25,7 +26,7 @@ module Fulmar
25
26
  end
26
27
 
27
28
  def remote_shell
28
- storage['remote_shell'] ||= new_shell(configuration[:remote_path], configuration[:hostname])
29
+ storage['remote_shell'] ||= new_shell(configuration[:remote_path], (configuration[:user] ? configuration[:user]+'@' : '')+configuration[:hostname])
29
30
  end
30
31
 
31
32
  def file_sync
@@ -61,6 +62,18 @@ module Fulmar
61
62
  @storage[configuration.environment] ||= {}
62
63
  @storage[configuration.environment][configuration.target] ||= {}
63
64
  end
65
+
66
+ def info(text)
67
+ puts (ENV['TERM'] == 'xterm-256color' ? text.blue : "* Info: #{text}")
68
+ end
69
+
70
+ def warn(text)
71
+ puts (ENV['TERM'] == 'xterm-256color' ? text.magenta : "* Warning: #{text}")
72
+ end
73
+
74
+ def error(text)
75
+ puts (ENV['TERM'] == 'xterm-256color' ? text.light_red : "* Error: #{text}")
76
+ end
64
77
  end
65
78
  end
66
79
  end
@@ -2,6 +2,7 @@ module Fulmar
2
2
  module Domain
3
3
  module Service
4
4
  module Helper
5
+ # Provides access helper to the database service from within a task
5
6
  module DatabaseHelper
6
7
  def database
7
8
  storage['database'] ||= Fulmar::Infrastructure::Service::Database::DatabaseService.new configuration
@@ -4,6 +4,7 @@ module Fulmar
4
4
  module Domain
5
5
  module Service
6
6
  module Helper
7
+ # Provides access helper to the flow service from within a task
7
8
  module FlowHelper
8
9
  def flow
9
10
  storage['flow'] ||= Fulmar::Infrastructure::Service::FlowService.new remote_shell, configuration
@@ -1,4 +1,4 @@
1
1
  # Provides a global version number
2
2
  module Fulmar
3
- VERSION = '1.0.0'
3
+ VERSION = '1.1.0'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fulmar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Siegl
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-27 00:00:00.000000000 Z
12
+ date: 2015-03-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -40,19 +40,19 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  version: '10'
42
42
  - !ruby/object:Gem::Dependency
43
- name: git
43
+ name: rugged
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '1.2'
48
+ version: '0'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '1.2'
55
+ version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: mysql2
58
58
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +107,20 @@ dependencies:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
109
  version: 0.1.0
110
+ - !ruby/object:Gem::Dependency
111
+ name: colorize
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
110
124
  description: Fulmar is a task manager for deployments.
111
125
  email:
112
126
  - j.siegl@core4.de