fulmar 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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