avodeploy 0.4
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 +7 -0
- data/Gemfile +4 -0
- data/LICENSE +340 -0
- data/README.md +35 -0
- data/Rakefile +2 -0
- data/avodeploy.gemspec +29 -0
- data/bin/avo +133 -0
- data/lib/avocado/Gemfile +9 -0
- data/lib/avocado/bootstrap.rb +99 -0
- data/lib/avocado/command_execution_result.rb +26 -0
- data/lib/avocado/config.rb +113 -0
- data/lib/avocado/core_ext/hash_insert_at.rb +42 -0
- data/lib/avocado/core_ext/string_colors.rb +45 -0
- data/lib/avocado/deployment.rb +76 -0
- data/lib/avocado/multi_io.rb +40 -0
- data/lib/avocado/scm_provider/git_scm_provider.rb +71 -0
- data/lib/avocado/scm_provider/scm_provider.rb +68 -0
- data/lib/avocado/skel/manifest_template.rb.erb +117 -0
- data/lib/avocado/strategy/base.rb +29 -0
- data/lib/avocado/strategy/local_copy.rb +99 -0
- data/lib/avocado/target.rb +49 -0
- data/lib/avocado/task/local_task_execution_environment.rb +127 -0
- data/lib/avocado/task/remote_task_execution_environment.rb +112 -0
- data/lib/avocado/task/task.rb +84 -0
- data/lib/avocado/task/task_dependency.rb +25 -0
- data/lib/avocado/task/task_execution_environment.rb +86 -0
- data/lib/avocado/task/task_manager.rb +183 -0
- data/lib/avocado/version.rb +21 -0
- metadata +170 -0
data/lib/avocado/Gemfile
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
=begin
|
2
|
+
AVOCADO
|
3
|
+
The flexible and easy to use deployment framework for web applications
|
4
|
+
|
5
|
+
This program is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU General Public License Version 2
|
7
|
+
as published by the Free Software Foundation.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program; if not, write to the Free Software
|
16
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
=end
|
18
|
+
|
19
|
+
module Avocado
|
20
|
+
class Bootstrap
|
21
|
+
# Runs the avocado bootstrap
|
22
|
+
#
|
23
|
+
# @param stage [Symbol] the stage to bootstrap
|
24
|
+
# @param verbose [Boolean] run in verbose mode
|
25
|
+
# @param debug [Boolean] run in boolean mode
|
26
|
+
def self.run(stage, verbose = false, debug = false)
|
27
|
+
if stage.is_a?(String)
|
28
|
+
stage = stage.to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
require File.join(File.dirname(__FILE__), 'core_ext/string_colors.rb')
|
32
|
+
require File.join(File.dirname(__FILE__), 'core_ext/hash_insert_at.rb')
|
33
|
+
|
34
|
+
require File.join(File.dirname(__FILE__), 'task/task.rb')
|
35
|
+
require File.join(File.dirname(__FILE__), 'task/task_dependency.rb')
|
36
|
+
require File.join(File.dirname(__FILE__), 'task/task_manager.rb')
|
37
|
+
require File.join(File.dirname(__FILE__), 'task/task_execution_environment.rb')
|
38
|
+
require File.join(File.dirname(__FILE__), 'task/local_task_execution_environment.rb')
|
39
|
+
require File.join(File.dirname(__FILE__), 'task/remote_task_execution_environment.rb')
|
40
|
+
|
41
|
+
require File.join(File.dirname(__FILE__), 'scm_provider/scm_provider.rb')
|
42
|
+
require File.join(File.dirname(__FILE__), 'scm_provider/git_scm_provider.rb')
|
43
|
+
|
44
|
+
require File.join(File.dirname(__FILE__), 'multi_io.rb')
|
45
|
+
require File.join(File.dirname(__FILE__), 'command_execution_result.rb')
|
46
|
+
require File.join(File.dirname(__FILE__), 'target.rb')
|
47
|
+
require File.join(File.dirname(__FILE__), 'config.rb')
|
48
|
+
require File.join(File.dirname(__FILE__), 'deployment.rb')
|
49
|
+
|
50
|
+
begin
|
51
|
+
# defaults
|
52
|
+
Avocado::Deployment.configure do
|
53
|
+
set :stage, stage
|
54
|
+
end
|
55
|
+
|
56
|
+
if File.exist?(Dir.pwd.concat('/Avofile')) == false
|
57
|
+
raise RuntimeError, 'Could not find Avofile. Run `avo install` first.'
|
58
|
+
end
|
59
|
+
|
60
|
+
instance = Avocado::Deployment.instance
|
61
|
+
|
62
|
+
# load user config initially to determine strategy
|
63
|
+
begin
|
64
|
+
load File.join(Dir.pwd, 'Avofile')
|
65
|
+
rescue RuntimeError => e
|
66
|
+
# `find_chain_index_containing': could not find a chain containing task create_deployment_tarball (RuntimeError)
|
67
|
+
# error not neccessary because dependencies are not loaded
|
68
|
+
end
|
69
|
+
|
70
|
+
if debug
|
71
|
+
instance.log.level = Logger::DEBUG
|
72
|
+
elsif verbose
|
73
|
+
instance.log.level = Logger::INFO
|
74
|
+
else
|
75
|
+
instance.log.level = instance.config.get(:log_level)
|
76
|
+
end
|
77
|
+
|
78
|
+
instance.log.debug "Loading deployment strategy #{instance.config.get(:strategy).to_s}..."
|
79
|
+
|
80
|
+
# load strategy
|
81
|
+
# @todo pruefen
|
82
|
+
require File.join(File.dirname(__FILE__), "strategy/base.rb")
|
83
|
+
require File.join(File.dirname(__FILE__), "strategy/#{instance.config.get(:strategy).to_s}.rb")
|
84
|
+
|
85
|
+
|
86
|
+
instance.log.debug "Loading user configuration..."
|
87
|
+
|
88
|
+
# override again by user config to allow manipulation of tasks
|
89
|
+
load File.join(Dir.pwd, 'Avofile')
|
90
|
+
rescue Exception => e
|
91
|
+
Avocado::Deployment.instance.log.error e.message.red
|
92
|
+
|
93
|
+
Kernel.exit(true)
|
94
|
+
end
|
95
|
+
|
96
|
+
Avocado::Deployment.instance
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
=begin
|
2
|
+
AVOCADO
|
3
|
+
The flexible and easy to use deployment framework for web applications
|
4
|
+
|
5
|
+
This program is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU General Public License Version 2
|
7
|
+
as published by the Free Software Foundation.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program; if not, write to the Free Software
|
16
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
=end
|
18
|
+
|
19
|
+
module Avocado
|
20
|
+
class CommandExecutionResult
|
21
|
+
attr_accessor :stdin
|
22
|
+
attr_accessor :stdout
|
23
|
+
attr_accessor :stderr
|
24
|
+
attr_accessor :retval
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
=begin
|
2
|
+
AVOCADO
|
3
|
+
The flexible and easy to use deployment framework for web applications
|
4
|
+
|
5
|
+
This program is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU General Public License Version 2
|
7
|
+
as published by the Free Software Foundation.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program; if not, write to the Free Software
|
16
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
=end
|
18
|
+
|
19
|
+
module Avocado
|
20
|
+
class Config
|
21
|
+
|
22
|
+
attr_reader :config
|
23
|
+
attr_reader :stages
|
24
|
+
attr_reader :targets
|
25
|
+
|
26
|
+
# Intializes the config object
|
27
|
+
def initialize
|
28
|
+
@config = setup_config_defaults
|
29
|
+
@stages = {}
|
30
|
+
@targets = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Sets a configuration item
|
34
|
+
#
|
35
|
+
# @param key [Symbol] configuration key
|
36
|
+
# @param value [mixed] configuration value
|
37
|
+
def set(key, value)
|
38
|
+
@config[key] = value
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a configuration item if set
|
42
|
+
#
|
43
|
+
# @param key [Symbol] configuration key
|
44
|
+
# @return [mixed] configuration value
|
45
|
+
def get(key)
|
46
|
+
raise ArgumentError, "key #{key} is not set" unless @config.has_key?(key)
|
47
|
+
|
48
|
+
@config[key]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Defines a task
|
52
|
+
#
|
53
|
+
# @param name [Symbol] task name
|
54
|
+
# @param options [Hash] task options
|
55
|
+
# @param block [Block] the code to be executed when the task is started
|
56
|
+
def task(name, options = {}, &block)
|
57
|
+
Avocado::Deployment.instance.task_manager.add_task(name, options, &block)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Defines a stage
|
61
|
+
#
|
62
|
+
# @param name [Symbol] stage name
|
63
|
+
# @param options [Hash] stage options
|
64
|
+
# @param block [Block] the stage configuration
|
65
|
+
def setup_stage(name, options = {}, &block)
|
66
|
+
if options.has_key?(:desc)
|
67
|
+
stages[name] = options[:desc]
|
68
|
+
end
|
69
|
+
|
70
|
+
if name == get(:stage)
|
71
|
+
instance_eval(&block)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Defines a deployment target
|
76
|
+
#
|
77
|
+
# @param name [Symbol] the deployment targets' name
|
78
|
+
# @param options [Hash] target options
|
79
|
+
def target(name, options = {})
|
80
|
+
@targets[name] = Avocado::Target.new(name, options)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Merges the configuration with another config hash
|
84
|
+
#
|
85
|
+
# @param other_config [Hash] configuration hash
|
86
|
+
# @return [Hash] the merged hash
|
87
|
+
def merge(other_config)
|
88
|
+
@config.merge(other_config)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
# Sets up configuration defaults
|
93
|
+
#
|
94
|
+
# @return [Hash] configuration defaults
|
95
|
+
def setup_config_defaults
|
96
|
+
{
|
97
|
+
:project_name => '',
|
98
|
+
:scm => :git,
|
99
|
+
:repo_url => '',
|
100
|
+
:branch => :master,
|
101
|
+
:ssh_host => '',
|
102
|
+
:ssh_user => 'root',
|
103
|
+
:ssh_auth => :pubkey,
|
104
|
+
:deploy_dir => '/var/www/',
|
105
|
+
:stage => :production,
|
106
|
+
:strategy => :local_copy,
|
107
|
+
:ignore_files => [],
|
108
|
+
:log_level => Logger::WARN,
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
=begin
|
2
|
+
AVOCADO
|
3
|
+
The flexible and easy to use deployment framework for web applications
|
4
|
+
|
5
|
+
This program is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU General Public License Version 2
|
7
|
+
as published by the Free Software Foundation.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program; if not, write to the Free Software
|
16
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
=end
|
18
|
+
|
19
|
+
class Hash
|
20
|
+
|
21
|
+
# Inserts a Key/Value-Pair at a specific position of in a Hash
|
22
|
+
#
|
23
|
+
# @param position [Symbol] the position to add the new pair, either `:before` or `:after`
|
24
|
+
def insert_at(position, key, kvpair)
|
25
|
+
raise ArgumentError, 'position must be either :before or :after' unless [:before, :after].include?(position)
|
26
|
+
|
27
|
+
arr = to_a
|
28
|
+
pos = arr.index(arr.assoc(key))
|
29
|
+
|
30
|
+
if pos && position == :after
|
31
|
+
pos += 1
|
32
|
+
end
|
33
|
+
|
34
|
+
if pos
|
35
|
+
arr.insert(pos, kvpair)
|
36
|
+
else
|
37
|
+
arr << kvpair
|
38
|
+
end
|
39
|
+
|
40
|
+
replace Hash[arr]
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
=begin
|
2
|
+
AVOCADO
|
3
|
+
The flexible and easy to use deployment framework for web applications
|
4
|
+
|
5
|
+
This program is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU General Public License Version 2
|
7
|
+
as published by the Free Software Foundation.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program; if not, write to the Free Software
|
16
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
=end
|
18
|
+
|
19
|
+
class String
|
20
|
+
|
21
|
+
# Paints the string red on CLI
|
22
|
+
def red
|
23
|
+
"\033[31m#{self}\033[0m"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Paints the string green on CLI
|
27
|
+
def green
|
28
|
+
"\033[32m#{self}\033[0m"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Paints the string cyan on CLI
|
32
|
+
def cyan
|
33
|
+
"\033[36m#{self}\033[0m"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Paints the string yellow on CLI
|
37
|
+
def yellow
|
38
|
+
"\e[33m#{self}\e[0m"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Paints the string gray on CLI
|
42
|
+
def gray
|
43
|
+
"\033[37m#{self}\033[0m"
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
=begin
|
2
|
+
AVOCADO
|
3
|
+
The flexible and easy to use deployment framework for web applications
|
4
|
+
|
5
|
+
This program is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU General Public License Version 2
|
7
|
+
as published by the Free Software Foundation.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program; if not, write to the Free Software
|
16
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
=end
|
18
|
+
|
19
|
+
module Avocado
|
20
|
+
class Deployment
|
21
|
+
|
22
|
+
attr_accessor :config
|
23
|
+
attr_accessor :task_manager
|
24
|
+
attr_reader :log
|
25
|
+
attr_reader :log_file
|
26
|
+
|
27
|
+
# Initializes the deployment
|
28
|
+
def initialize
|
29
|
+
@stages = {}
|
30
|
+
@task_manager = Avocado::TaskManager.new
|
31
|
+
@config = Avocado::Config.new
|
32
|
+
|
33
|
+
@log = ::Logger.new(STDOUT)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Configures the deployment
|
37
|
+
#
|
38
|
+
# @param block [Block] configuration block
|
39
|
+
def self.configure(&block)
|
40
|
+
@instance = self.instance
|
41
|
+
@instance.config.instance_eval(&block)
|
42
|
+
|
43
|
+
# @todo check config and throw exception
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the deployment instance
|
47
|
+
#
|
48
|
+
# @return [Deployment] the deployment instance
|
49
|
+
def self.instance
|
50
|
+
if @instance.nil?
|
51
|
+
@instance = self.new
|
52
|
+
end
|
53
|
+
|
54
|
+
@instance
|
55
|
+
end
|
56
|
+
|
57
|
+
# Handles exceptions
|
58
|
+
#
|
59
|
+
# @param [Exception] the exception to handle
|
60
|
+
def handle_abort(e)
|
61
|
+
if e.class != SystemExit
|
62
|
+
@log.error e.message.red
|
63
|
+
@log.info "cleaning up..."
|
64
|
+
|
65
|
+
task_manager.invoke_task_oneshot(:cleanup_local)
|
66
|
+
|
67
|
+
#if e.kind_of?(::Net::SSH::AuthenticationFailed) == false
|
68
|
+
# task_manager.invoke_task_oneshot(:cleanup_remote)
|
69
|
+
#end
|
70
|
+
|
71
|
+
Kernel.exit(true)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
=begin
|
2
|
+
AVOCADO
|
3
|
+
The flexible and easy to use deployment framework for web applications
|
4
|
+
|
5
|
+
This program is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU General Public License Version 2
|
7
|
+
as published by the Free Software Foundation.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program; if not, write to the Free Software
|
16
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
=end
|
18
|
+
|
19
|
+
module Avocado
|
20
|
+
class MultiIO
|
21
|
+
# Initializes the MultiIO with various target
|
22
|
+
#
|
23
|
+
# @param targets [Array] targets to handle
|
24
|
+
def initialize(*targets)
|
25
|
+
@targets = targets
|
26
|
+
end
|
27
|
+
|
28
|
+
# Writes to all targets
|
29
|
+
#
|
30
|
+
# @param args [mixed] arguments
|
31
|
+
def write(*args)
|
32
|
+
@targets.each {|t| t.write(*args)}
|
33
|
+
end
|
34
|
+
|
35
|
+
# Closes the targets
|
36
|
+
def close
|
37
|
+
@targets.each(&:close)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|