avodeploy 0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'awesome_print'
4
+ gem 'table_print'
5
+
6
+ gem 'net-ssh'
7
+ gem 'net-scp'
8
+
9
+ gem 'thor'
@@ -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