fulmar 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/CODE_OF_CONDUCT.md +13 -0
  4. data/Gemfile +13 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +23 -0
  7. data/bin/fulmar +3 -0
  8. data/fulmar.gemspec +28 -0
  9. data/lib/fulmar/domain/service/application_service.rb +47 -0
  10. data/lib/fulmar/domain/service/cache_service.rb +30 -0
  11. data/lib/fulmar/domain/service/config_rendering_service.rb +26 -0
  12. data/lib/fulmar/domain/service/configuration_service.rb +115 -0
  13. data/lib/fulmar/domain/service/file_sync_service.rb +23 -0
  14. data/lib/fulmar/domain/service/initialization_service.rb +7 -0
  15. data/lib/fulmar/domain/task/setup.rake +6 -0
  16. data/lib/fulmar/domain/task/versions.rake +54 -0
  17. data/lib/fulmar/infrastructure/service/cache/dummy_cache_service.rb +25 -0
  18. data/lib/fulmar/infrastructure/service/cache/neos_cache_service.rb +25 -0
  19. data/lib/fulmar/infrastructure/service/cache/symfony_cache_service.rb +28 -0
  20. data/lib/fulmar/infrastructure/service/composer_service.rb +16 -0
  21. data/lib/fulmar/infrastructure/service/database/database_service.rb +151 -0
  22. data/lib/fulmar/infrastructure/service/git_service.rb +67 -0
  23. data/lib/fulmar/infrastructure/service/shell_service.rb +10 -0
  24. data/lib/fulmar/infrastructure/service/transfer/base.rb +58 -0
  25. data/lib/fulmar/infrastructure/service/transfer/rsync.rb +58 -0
  26. data/lib/fulmar/infrastructure/service/transfer/rsync_with_versions.rb +194 -0
  27. data/lib/fulmar/infrastructure/service/tunnel_service.rb +49 -0
  28. data/lib/fulmar/service/bootstrap_service.rb +14 -0
  29. data/lib/fulmar/service/common_helper_service.rb +48 -0
  30. data/lib/fulmar/service/helper_service.rb +37 -0
  31. data/lib/fulmar/service/logger_service.rb +7 -0
  32. data/lib/fulmar/task_manager.rb +24 -0
  33. data/lib/fulmar/version.rb +4 -0
  34. data/test/rsync_with_versions.rb +20 -0
  35. metadata +177 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5cdfa8880f0018ba88c120cded8caf8d1a35ae5c
4
+ data.tar.gz: aef5b36b6585b9baf976596e44ed615bf944f655
5
+ SHA512:
6
+ metadata.gz: 0c141dd10381bfd94cd96062cf2c47c1c2b2f8c2b1fc986f109e8590a545839f9f7a6d9104d432989e0e3e079eb30d53dcfaa533025138551aaedadec811bb01
7
+ data.tar.gz: e4ba568f4667f92b3e2eeed12940fc1157c9cdfe4aacab6d5005441a0efd6cfb503280c4d4ad4583d42f76857d38d9607bf456c51b6f1fa6286a3c21d077bad9
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ /.idea/
16
+ *.gem
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fulmar.gemspec
4
+ gemspec
5
+
6
+ gem 'rake'
7
+ gem 'mysql2'
8
+ gem 'git'
9
+
10
+ source 'http://dione.core4.lan:9292' do
11
+ gem 'ruby_wings'
12
+ gem 'fulmar-shell', '>= 1.1.0'
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Gerrit Visscher
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # Fulmar
2
+
3
+ Fulmar is a task manager for deployments.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'fulmar'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install fulmar
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
data/bin/fulmar ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fulmar/task_manager'
data/fulmar.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fulmar/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'fulmar'
8
+ spec.version = Fulmar::VERSION
9
+ spec.authors = ['Jonas Siegl', 'Gerrit Visscher']
10
+ spec.email = %w(j.siegl@core4.de g.visscher@core4.de)
11
+ spec.summary = 'A deployment task manager.'
12
+ spec.description = 'Fulmar is a task manager for deployments.'
13
+ spec.homepage = 'http://git.core4.de/core4internal/fulmar'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+
23
+ spec.add_runtime_dependency 'rake', '~>10'
24
+ spec.add_runtime_dependency 'git', '~>1.2'
25
+ spec.add_runtime_dependency 'mysql2', '~>0.3'
26
+ spec.add_runtime_dependency 'fulmar-shell', '~>1.1', '>=1.1.2'
27
+ spec.add_runtime_dependency 'ruby_wings', '~>0.1', '>=0.1.0'
28
+ end
@@ -0,0 +1,47 @@
1
+ require 'rake'
2
+
3
+ module Fulmar
4
+ module Domain
5
+ module Service
6
+ # The main application which extends rake
7
+ class ApplicationService < Rake::Application
8
+ def initialize
9
+ super
10
+ @rakefiles = %w(fulmarfile Fulmarfile fulmarfile.rb Fulmarfile.rb)
11
+ @rakefiles.push(*fulmar_tasks)
12
+ end
13
+
14
+ def name
15
+ 'fulmar'
16
+ end
17
+
18
+ def run
19
+ Rake.application = self
20
+ super
21
+ end
22
+
23
+ def define_task(task_class, *args, &block)
24
+ super(task_class, *args, &wrap_environment(&block))
25
+ end
26
+
27
+ def wrap_environment
28
+ Proc.new do
29
+ configuration = Fulmar::Domain::Service::ConfigurationService.instance
30
+ environment = configuration.environment
31
+ target = configuration.target
32
+
33
+ yield if block_given?
34
+
35
+ configuration.environment = environment unless environment.nil?
36
+ configuration.target = target unless target.nil?
37
+ end
38
+ end
39
+
40
+ # Add fulmar application tasks
41
+ def fulmar_tasks
42
+ Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), '../', 'task')) + '/*.rake')
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ require 'fulmar/infrastructure/cache/dummy_cache_service'
2
+ require 'fulmar/infrastructure/cache/neos_cache_service'
3
+ require 'fulmar/infrastructure/cache/symfony_cache_service'
4
+
5
+ module Fulmar
6
+ module Domain
7
+ module Service
8
+ # Provides a common interface for all environment specific cache services
9
+ class CacheService
10
+ attr_reader :type, :cache
11
+
12
+ def initialize(shell, config, type = :none)
13
+ @type = type
14
+ @cache = case type
15
+ when :neos
16
+ Fulmar::Infrastructure::Service::Cache::NeosCacheService.new(shell, config)
17
+ when :symfony
18
+ Fulmar::Infrastructure::Service::Cache::SymfonyCacheService.new(shell, config)
19
+ else
20
+ Fulmar::Infrastructure::Service::Cache::DummyCacheService.new(shell, config)
21
+ end
22
+ end
23
+
24
+ def method_missing(name, parameters)
25
+ @cache.call(name, parameters)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ require 'erb'
2
+
3
+ module Fulmar
4
+ module Domain
5
+ module Service
6
+ # Renders templates of config files
7
+ class ConfigRenderingService
8
+ def initialize(config)
9
+ @config = config
10
+ end
11
+
12
+ def render
13
+ return unless @config[:config_templates]
14
+ @config[:config_templates].each do |template|
15
+ fail "Template filenames must end in .erb - '#{template}' does not" unless template[-4, 4] == '.erb'
16
+ fail "Cannot render missing config file '#{template}'" unless File.exist? template
17
+
18
+ renderer = ERB.new(File.read(template))
19
+ result_path = File.dirname(template) + '/' + File.basename(template, '.erb')
20
+ File.open(result_path, 'w') { |config_file| config_file.write(renderer.result(binding)) }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,115 @@
1
+ require 'yaml'
2
+
3
+ module Fulmar
4
+ module Domain
5
+ module Service
6
+ # Loads and prepares the configuration from the yaml file
7
+ # TODO: Clone target configuration when used as a parameter to another service so an environment change won't affect it
8
+ class ConfigurationService
9
+ FULMAR_FILE = 'Fulmarfile'
10
+ FULMAR_CONFIGURATION = 'FulmarConfiguration'
11
+ DEPLOYMENT_CONFIG_FILE = 'deployment.yml'
12
+
13
+ include Singleton
14
+
15
+ attr_reader :environment, :target
16
+
17
+ def initialize
18
+ @environment = nil
19
+ @target = nil
20
+ end
21
+
22
+ # Allow access of configuration via array/hash access methods (read access)
23
+ def [](id)
24
+ (@environment.nil? || @target.nil?) ? nil : configuration[:environments][@environment][@target][id]
25
+ end
26
+
27
+ # Allow access of configuration via array/hash access methods (write access)
28
+ def []=(id, value)
29
+ if @environment && @target
30
+ configuration[:environments][@environment][@target][id] = value
31
+ else
32
+ fail 'Environment or target not set. Please set both variables via configuration.environment = \'xxx\' / '\
33
+ 'configuration.target = \'yyy\''
34
+ end
35
+ end
36
+
37
+ def to_hash
38
+ (@environment.nil? || @target.nil?) ? configuration : configuration[:environments][@environment][@target]
39
+ end
40
+
41
+ def base_path
42
+ @base_path ||= lookup_base_path
43
+ end
44
+
45
+ def configuration
46
+ @config ||= load_configuration
47
+ end
48
+
49
+ def method_missing(name)
50
+ environment(name) if configuration[:environments][name]
51
+ end
52
+
53
+ def environment=(env)
54
+ @environment = env ? env.to_sym : nil
55
+ end
56
+
57
+ def target=(target)
58
+ @target = target ? target.to_sym : nil
59
+ end
60
+
61
+ # Merge another configuration into the currently active one
62
+ # Useful for supplying a default configuration, as values are not overwritten.
63
+ # Hashes are merged.
64
+ # @param [Hash] other
65
+ def merge(other)
66
+ if @environment && @target
67
+ configuration[:environments][@environment][@target] = other.deep_merge(configuration[:environments][@environment][@target])
68
+ end
69
+ end
70
+
71
+ protected
72
+
73
+ def lookup_base_path
74
+ fulmar_file = Fulmar::Service::HelperService.reverse_file_lookup(Dir.pwd, FULMAR_FILE)
75
+
76
+ unless fulmar_file
77
+ puts 'Fulmar setup not found. Please run "fulmar setup" to initialize the application in the current directory.'
78
+ exit
79
+ end
80
+
81
+ File.dirname(fulmar_file)
82
+ end
83
+
84
+ # Fills a target with all globally set variables so all necessary information
85
+ # is found within each target
86
+ def fill_target(env, target)
87
+ @config[:environments][env][target] = @config[:environments][:all].deep_merge(@config[:environments][env][target])
88
+
89
+ unless @config[:environments][env][target][:host].blank?
90
+ host = @config[:environments][env][target][:host].to_sym
91
+ if @config[:hosts] && @config[:hosts][host]
92
+ @config[:hosts][host].each do
93
+ @config[:environments][env][target] = @config[:hosts][host].deep_merge(@config[:environments][env][target])
94
+ end
95
+ else
96
+ fail "Host #{host} is not configured."
97
+ end
98
+ end
99
+ end
100
+
101
+ # Loads the configuration from the YAML file and populates all targets
102
+ def load_configuration
103
+ @config = YAML.load_file(base_path + '/' + DEPLOYMENT_CONFIG_FILE).symbolize
104
+
105
+ # Iterate over all environments and targets to prepare them
106
+ @config[:environments].each_key do |env|
107
+ next if env == :all
108
+ @config[:environments][env].each_key { |target| fill_target(env, target) }
109
+ end
110
+ @config
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,23 @@
1
+
2
+ require 'fulmar/infrastructure/service/transfer/rsync'
3
+ require 'fulmar/infrastructure/service/transfer/rsync_with_versions'
4
+
5
+ module Fulmar
6
+ # Creates the required transfer model from the configuration
7
+ class FileSync
8
+ def self.create_transfer(config)
9
+ case config[:type]
10
+ when 'rsync_with_versions'
11
+ transfer_model = Fulmar::Infrastructure::Service::Transfer::RsyncWithVersions.new(config)
12
+ when 'rsync'
13
+ transfer_model = Fulmar::Infrastructure::Service::Transfer::Rsync.new(config)
14
+ else
15
+ help = config[:type] == '' ? 'Add a "type: " field to your deployment yaml file. ' : ''
16
+ transfer_model = nil
17
+ fail "Transfer type '#{config[:type]}' is not valid. #{help}Valid values are: rsync, rsync_with_versions."
18
+ end
19
+
20
+ transfer_model
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ module Fulmar
2
+ module Domain
3
+ module Service
4
+ class InitializationService; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ require 'fulmar'
2
+
3
+ desc 'Setup fulmar'
4
+ task :setup do
5
+ puts 'run setup'
6
+ end
@@ -0,0 +1,54 @@
1
+ include Fulmar::Domain::Service::CommonHelperService
2
+
3
+ namespace :versions do
4
+
5
+ task :load_config do
6
+ # load the configuration from the config gem
7
+ end
8
+
9
+ @versioned_servers = {}
10
+ full_configuration[:environments].each_pair do |env, targets|
11
+ next if env == :all
12
+
13
+ targets.each_pair do |target, config|
14
+ @versioned_servers["#{env}:#{target}"] = config if config[:type].to_s == 'rsync_with_versions'
15
+ end
16
+ end
17
+
18
+ desc 'List existing versions on the server'
19
+ task :list do
20
+ if @versioned_servers.empty?
21
+ puts 'None of the configured environments supports versioning.'
22
+ else
23
+ puts 'Environments which support versioning:'
24
+ @versioned_servers.each_key do |env|
25
+ puts "- #{env}"
26
+ end
27
+
28
+ puts "\nSo run one of these now:"
29
+ @versioned_servers.each_key do |env|
30
+ puts "$ fulmar versions:list:#{env}"
31
+ end
32
+ end
33
+ end
34
+
35
+ unless @versioned_servers.empty?
36
+
37
+ namespace :list do
38
+
39
+ @versioned_servers.each_key do |env|
40
+
41
+ desc "List available versions for environment \"#{env}\""
42
+ task env do
43
+ configuration.environment = env.split(':').first
44
+ configuration.target = env.split(':').last
45
+ file_sync.list_releases(false).each{|item| puts item}
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,25 @@
1
+ module Fulmar
2
+ module Infrastructure
3
+ module Service
4
+ module Cache
5
+ # Implements no cache handling
6
+ class DummyCacheService
7
+ # @param [Fulmar::Infrastructure::Service::ShellService] shell
8
+ # @param [Hash] config
9
+ def initialize(shell, config)
10
+ @remote_shell = shell
11
+ @config = config
12
+ end
13
+
14
+ def clear
15
+ true
16
+ end
17
+
18
+ def warmup
19
+ true
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module Fulmar
2
+ module Infrastructure
3
+ module Service
4
+ module Cache
5
+ # Implements Neos cache handling
6
+ class NeosCacheService
7
+ # @param [Fulmar::Infrastructure::Service::ShellService] shell
8
+ # @param [Hash] config
9
+ def initialize(shell, config)
10
+ @remote_shell = shell
11
+ @config = config
12
+ end
13
+
14
+ def clear
15
+ @remote_shell.run "FLOW_CONTEXT=\"#{@config[:neos][:environment]}\" ./flow flow:cache:flush --force"
16
+ end
17
+
18
+ def warmup
19
+ @remote_shell.run "FLOW_CONTEXT=\"#{@config[:neos][:environment]}\" ./flow flow:cache:warmup"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ module Fulmar
2
+ module Infrastructure
3
+ module Service
4
+ module Cache
5
+ # Implements Symfony cache handling
6
+ class SymfonyCacheService
7
+ # @param [Fulmar::Infrastructure::Service::ShellService] shell
8
+ # @param [Hash] config
9
+ def initialize(shell, config)
10
+ @remote_shell = shell
11
+ @config = config
12
+ end
13
+
14
+ def clear
15
+ @remote_shell.run [
16
+ "rm -fr app/cache/#{@config[:symfony][:environment]}",
17
+ "php app/console cache:clear --env=#{@config[:symfony][:environment]}"
18
+ ]
19
+ end
20
+
21
+ def warmup
22
+ @remote_shell.run "php app/console cache:warmup --env=#{@config[:symfony][:environment]}"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ module Fulmar
2
+ module Infrastructure
3
+ module Service
4
+ # Provides access to composer
5
+ class ComposerService
6
+ def initialize(custom_path = '/usr/bin/env composer')
7
+ @path = custom_path
8
+ end
9
+
10
+ def execute(command, arguments = [])
11
+ system "#{@path} #{command} #{arguments.join(' ')} > /dev/null"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end