avodeploy 0.4.2 → 0.5
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 +4 -4
- data/CHANGELOG +20 -0
- data/README.md +1 -1
- data/avodeploy.gemspec +16 -14
- data/bin/avo +101 -104
- data/lib/avodeploy.rb +1 -0
- data/lib/avodeploy/bootstrap.rb +65 -73
- data/lib/avodeploy/command_execution_result.rb +6 -6
- data/lib/avodeploy/config.rb +120 -99
- data/lib/avodeploy/core_ext/string_colors.rb +9 -9
- data/lib/avodeploy/deployment.rb +43 -46
- data/lib/avodeploy/multi_io.rb +11 -11
- data/lib/avodeploy/scm_provider/bzr_scm_provider.rb +111 -0
- data/lib/avodeploy/scm_provider/git_scm_provider.rb +66 -45
- data/lib/avodeploy/scm_provider/scm_provider.rb +57 -43
- data/lib/avodeploy/skel/manifest_template.rb.erb +127 -116
- data/lib/avodeploy/strategy/base.rb +7 -7
- data/lib/avodeploy/strategy/local_copy.rb +99 -79
- data/lib/avodeploy/strategy/local_copy_partial.rb +86 -0
- data/lib/avodeploy/target.rb +32 -31
- data/lib/avodeploy/task/local_task_execution_environment.rb +112 -107
- data/lib/avodeploy/task/remote_task_execution_environment.rb +90 -94
- data/lib/avodeploy/task/task.rb +53 -42
- data/lib/avodeploy/task/task_dependency.rb +5 -5
- data/lib/avodeploy/task/task_execution_environment.rb +70 -59
- data/lib/avodeploy/task/task_manager.rb +187 -165
- data/lib/avodeploy/version.rb +1 -1
- metadata +7 -5
@@ -17,98 +17,94 @@
|
|
17
17
|
=end
|
18
18
|
|
19
19
|
module AvoDeploy
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
end
|
20
|
+
module Task
|
21
|
+
class RemoteTaskExecutionEnvironment < TaskExecutionEnvironment
|
22
|
+
|
23
|
+
attr_accessor :config
|
24
|
+
|
25
|
+
# Creates a connection between the local and the remote system over ssh
|
26
|
+
def establish_connection
|
27
|
+
AvoDeploy::Deployment.instance.log.debug "connecting to #{get(:user)}@#{get(:host)}..."
|
28
|
+
|
29
|
+
begin
|
30
|
+
@session = ::Net::SSH.start(get(:host), get(:user), port: get(:port), timeout: 30)
|
31
|
+
rescue ::Net::SSH::AuthenticationFailed => e
|
32
|
+
handle_abort e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Checks, if all utilities are available for the deployment process
|
37
|
+
# to be executed
|
38
|
+
#
|
39
|
+
# @param utils [Array] array with utilities to check
|
40
|
+
def check_util_availability(utils)
|
41
|
+
super(utils, 'remotely')
|
42
|
+
end
|
43
|
+
|
44
|
+
# Executes a command via ssh
|
45
|
+
#
|
46
|
+
# @param ssh [Net::SSH::Connection::Session] ssh session
|
47
|
+
# @param command [String] the command to execute
|
48
|
+
def ssh_exec!(ssh, command)
|
49
|
+
stdout_data = ""
|
50
|
+
stderr_data = ""
|
51
|
+
exit_code = nil
|
52
|
+
|
53
|
+
ssh.open_channel do |channel|
|
54
|
+
channel.exec(command) do |ch, success|
|
55
|
+
unless success
|
56
|
+
abort "FAILED: couldn't execute command (ssh.channel.exec)"
|
57
|
+
end
|
58
|
+
channel.on_data do |ch, data|
|
59
|
+
stdout_data+=data
|
60
|
+
end
|
61
|
+
|
62
|
+
channel.on_extended_data do |ch, type, data|
|
63
|
+
stderr_data+=data
|
64
|
+
end
|
65
|
+
|
66
|
+
channel.on_request("exit-status") do |ch, data|
|
67
|
+
exit_code = data.read_long
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
ssh.loop
|
72
|
+
|
73
|
+
result = AvoDeploy::CommandExecutionResult.new
|
74
|
+
result.stdin = command
|
75
|
+
result.stdout = stdout_data
|
76
|
+
result.stderr = stderr_data
|
77
|
+
result.retval = exit_code
|
78
|
+
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
82
|
+
# Executes a command on the remote system
|
83
|
+
#
|
84
|
+
# @param cmd [String] the command to execute
|
85
|
+
# @return [CommandExecutionResult] result of the command exection
|
86
|
+
def command(cmd)
|
87
|
+
AvoDeploy::Deployment.instance.log.info "Executing [" + cmd.yellow + "] on remote " + get(:name).to_s.cyan
|
88
|
+
|
89
|
+
result = AvoDeploy::CommandExecutionResult.new
|
90
|
+
|
91
|
+
begin
|
92
|
+
result = ssh_exec!(@session, cmd)
|
93
|
+
|
94
|
+
if result.stdout.nil? == false && result.stdout.empty? == false
|
95
|
+
AvoDeploy::Deployment.instance.log.debug "Stdout@#{get(:host)}: ".cyan + result.stdout.green
|
96
|
+
end
|
97
|
+
|
98
|
+
if result.stderr.nil? == false && result.stderr.empty? == false
|
99
|
+
AvoDeploy::Deployment.instance.log.debug "Stderr@#{get(:host)}: ".cyan + result.stderr.red
|
100
|
+
end
|
101
|
+
rescue Exception => e
|
102
|
+
handle_abort e
|
103
|
+
end
|
104
|
+
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
114
110
|
end
|
data/lib/avodeploy/task/task.rb
CHANGED
@@ -17,60 +17,71 @@
|
|
17
17
|
=end
|
18
18
|
|
19
19
|
module AvoDeploy
|
20
|
-
|
21
|
-
|
20
|
+
module Task
|
21
|
+
class Task
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
attr_accessor :name
|
24
|
+
attr_accessor :scope
|
25
|
+
attr_accessor :visibility
|
26
|
+
attr_accessor :block
|
27
|
+
attr_accessor :desc
|
28
|
+
attr_accessor :remote_only
|
29
|
+
attr_accessor :remote_except
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
# Creates a new task from a task block in the deployment configuration process
|
32
|
+
#
|
33
|
+
# @param name [Symbol] name of the task
|
34
|
+
# @param options [Hash] command options
|
35
|
+
# @param block [Block] code block of the task
|
36
|
+
# @return [Task] the task instance
|
37
|
+
def self.from_task_block(name, options, &block)
|
38
|
+
instance = self.new
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
+
instance.name = name
|
41
|
+
instance.block = block
|
40
42
|
|
41
|
-
|
43
|
+
instance.scope = :local
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
if options.has_key?(:scope) && options[:scope] == :remote
|
46
|
+
instance.scope = :remote
|
47
|
+
end
|
46
48
|
|
47
|
-
|
49
|
+
instance.visibility = :public
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
-
|
51
|
+
if options.has_key?(:visibility) && options[:visibility] == :private
|
52
|
+
instance.visibility = :private
|
53
|
+
end
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
55
|
+
if options.has_key?(:desc)
|
56
|
+
instance.desc = options[:desc]
|
57
|
+
end
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
+
if options.has_key?(:only)
|
60
|
+
instance.remote_only = options[:only]
|
61
|
+
end
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
# @return [mixed] result of the code block
|
64
|
-
def invoke(env)
|
65
|
-
raise ArgumentError 'env must be a valid TaskExecutionEnvironment' unless env.kind_of?(TaskExecutionEnvironment)
|
63
|
+
if options.has_key?(:except)
|
64
|
+
instance.remote_except = options[:except]
|
65
|
+
end
|
66
66
|
|
67
|
-
|
67
|
+
instance
|
68
|
+
end
|
68
69
|
|
69
|
-
|
70
|
+
# Runs the code of a task
|
71
|
+
#
|
72
|
+
# @param env [TaskExecutionEnvironment] the environment to invoke the task in
|
73
|
+
# @param options [Hash] a hash contining additional options
|
74
|
+
# @return [mixed] result of the code block
|
75
|
+
def invoke(env, options = {})
|
76
|
+
raise ArgumentError 'env must be a valid TaskExecutionEnvironment' unless env.kind_of?(TaskExecutionEnvironment)
|
70
77
|
|
71
|
-
|
72
|
-
end
|
78
|
+
avo = AvoDeploy::Deployment.instance
|
73
79
|
|
74
|
-
|
75
|
-
|
80
|
+
avo.log.debug "Running task #{@name}"
|
81
|
+
|
82
|
+
env.instance_eval(&@block)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
76
87
|
end
|
@@ -18,10 +18,10 @@
|
|
18
18
|
|
19
19
|
module AvoDeploy
|
20
20
|
module Task
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
class TaskDependency
|
22
|
+
attr_accessor :task_name
|
23
|
+
attr_accessor :dependent_task_name
|
24
|
+
attr_accessor :type
|
25
|
+
end
|
26
26
|
end
|
27
27
|
end
|
@@ -17,72 +17,83 @@
|
|
17
17
|
=end
|
18
18
|
|
19
19
|
module AvoDeploy
|
20
|
-
|
21
|
-
|
20
|
+
module Task
|
21
|
+
class TaskExecutionEnvironment
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
# @param config [Hash] deployment configuration
|
26
|
-
def initialize(config)
|
27
|
-
# @todo check
|
28
|
-
@config = config
|
29
|
-
end
|
23
|
+
attr_accessor :scm
|
24
|
+
attr_accessor :options
|
30
25
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
26
|
+
# Initialized the environment
|
27
|
+
#
|
28
|
+
# @param config [Hash] deployment configuration
|
29
|
+
def initialize(config)
|
30
|
+
# @todo check
|
31
|
+
@config = config
|
32
|
+
end
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
if command("command -v #{util} >/dev/null 2>&1 || exit 1;").retval == 1
|
46
|
-
msg = "command line utility '#{util}' is not installed #{system_name}"
|
34
|
+
# Runs a task without dependencies
|
35
|
+
#
|
36
|
+
# @param task_name [Symbol] task name to execute
|
37
|
+
# @return [Object] the task result
|
38
|
+
def run_nodeps(task_name)
|
39
|
+
AvoDeploy::Deployment.instance.task_manager.invoke_task_oneshot(task_name)
|
40
|
+
end
|
47
41
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
42
|
+
# Runs a task chain
|
43
|
+
#
|
44
|
+
# @param task_name [Symbol] task name to invoke
|
45
|
+
def run(task_name)
|
46
|
+
AvoDeploy::Deployment.instance.task_manager.invoke_task_chain_containing(task_name)
|
47
|
+
end
|
55
48
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
49
|
+
# Checks, if all utilities are available for the deployment process
|
50
|
+
# to be executed
|
51
|
+
#
|
52
|
+
# @param utils [Array] array with utilities to check
|
53
|
+
def check_util_availability(utils, system_name)
|
54
|
+
begin
|
55
|
+
utils.each do |util|
|
56
|
+
if command("command -v #{util} >/dev/null 2>&1 || exit 1;").retval == 1
|
57
|
+
msg = "command line utility '#{util}' is not installed #{system_name}"
|
62
58
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
59
|
+
raise RuntimeError, msg
|
60
|
+
end
|
61
|
+
end
|
62
|
+
rescue Exception => e
|
63
|
+
handle_abort e
|
64
|
+
end
|
65
|
+
end
|
70
66
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
67
|
+
# Returns the logger instance
|
68
|
+
#
|
69
|
+
# @return [Logger] log instance
|
70
|
+
def log
|
71
|
+
AvoDeploy::Deployment.instance.log
|
72
|
+
end
|
78
73
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
74
|
+
# Sets a configuration item
|
75
|
+
#
|
76
|
+
# @param key [Symbol] configuration key
|
77
|
+
# @param value [mixed] configuration value
|
78
|
+
def set(key, value)
|
79
|
+
@config[key] = value
|
80
|
+
end
|
85
81
|
|
86
|
-
|
87
|
-
|
82
|
+
# Returns a configuration item if set
|
83
|
+
#
|
84
|
+
# @param key [Symbol] configuration key
|
85
|
+
# @return [mixed] configuration value
|
86
|
+
def get(key)
|
87
|
+
@config[key]
|
88
|
+
end
|
89
|
+
|
90
|
+
# Shorthand for exception handling
|
91
|
+
#
|
92
|
+
# @param e [Exception] the exception to handle
|
93
|
+
def handle_abort(e)
|
94
|
+
AvoDeploy::Deployment.instance.handle_abort(e)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
88
99
|
end
|