avodeploy 0.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +14 -0
  3. data/README.md +8 -5
  4. data/avodeploy.gemspec +3 -4
  5. data/bin/avo +14 -12
  6. data/lib/avodeploy.rb +29 -0
  7. data/lib/{avocado → avodeploy}/bootstrap.rb +24 -30
  8. data/lib/{avocado → avodeploy}/command_execution_result.rb +1 -1
  9. data/lib/{avocado → avodeploy}/config.rb +8 -4
  10. data/lib/{avocado → avodeploy}/core_ext/hash_insert_at.rb +0 -0
  11. data/lib/{avocado → avodeploy}/core_ext/string_colors.rb +0 -0
  12. data/lib/{avocado → avodeploy}/deployment.rb +3 -3
  13. data/lib/{avocado → avodeploy}/multi_io.rb +1 -1
  14. data/lib/avodeploy/scm_provider/git_scm_provider.rb +73 -0
  15. data/lib/avodeploy/scm_provider/scm_provider.rb +70 -0
  16. data/lib/{avocado → avodeploy}/skel/manifest_template.rb.erb +1 -1
  17. data/lib/{avocado → avodeploy}/strategy/base.rb +1 -1
  18. data/lib/avodeploy/strategy/local_copy.rb +101 -0
  19. data/lib/{avocado → avodeploy}/target.rb +3 -1
  20. data/lib/avodeploy/task/local_task_execution_environment.rb +127 -0
  21. data/lib/avodeploy/task/remote_task_execution_environment.rb +114 -0
  22. data/lib/avodeploy/task/task.rb +76 -0
  23. data/lib/{avocado → avodeploy}/task/task_dependency.rb +8 -6
  24. data/lib/avodeploy/task/task_execution_environment.rb +88 -0
  25. data/lib/avodeploy/task/task_manager.rb +185 -0
  26. data/lib/{avocado → avodeploy}/version.rb +2 -2
  27. metadata +27 -40
  28. data/lib/avocado/Gemfile +0 -9
  29. data/lib/avocado/scm_provider/git_scm_provider.rb +0 -71
  30. data/lib/avocado/scm_provider/scm_provider.rb +0 -68
  31. data/lib/avocado/strategy/local_copy.rb +0 -99
  32. data/lib/avocado/task/local_task_execution_environment.rb +0 -127
  33. data/lib/avocado/task/remote_task_execution_environment.rb +0 -112
  34. data/lib/avocado/task/task.rb +0 -84
  35. data/lib/avocado/task/task_execution_environment.rb +0 -86
  36. data/lib/avocado/task/task_manager.rb +0 -183
@@ -1,9 +0,0 @@
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'
@@ -1,71 +0,0 @@
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 GitScmProvider
21
-
22
- # Initializes the provider
23
- #
24
- # @param env [TaskExecutionEnvironment] Environment for the commands to be executed in
25
- def initialize(env)
26
- raise ArgumentError, "env must be a TaskExecutionEnvironment" unless env.kind_of?(TaskExecutionEnvironment)
27
-
28
- @env = env
29
- end
30
-
31
- # Checks out repository code from a system and switches to the given branch
32
- #
33
- # @param url [String] the repository location
34
- # @param local_dir [String] path to the working copy
35
- # @param branch [String] the branch to check out
36
- def checkout_from_remote(url, local_dir, branch)
37
- res = @env.command("git clone #{url} #{local_dir}")
38
- raise RuntimeError, "Could not clone from git url #{url}" unless res.retval == 0
39
-
40
- @env.chdir(local_dir)
41
- res = @env.command("git checkout #{branch}")
42
- @env.chdir('../')
43
-
44
- raise RuntimeError, "could not switch to branch #{branch}" unless res.retval == 0
45
- end
46
-
47
- # Returns the current revision of the working copy
48
- #
49
- # @return [String] the current revision of the working copy
50
- def revision
51
- res = @env.command("git rev-parse HEAD")
52
-
53
- res.stdout.gsub("\n", "")
54
- end
55
-
56
- # Returns scm files to be executed in the deployment process
57
- #
58
- # @return [Array] array of scm control files
59
- def scm_files
60
- [ '.git', '.gitignore' ]
61
- end
62
-
63
- # Returns the scm tools that have to be installed on specific systems
64
- #
65
- # @return [Array] array of utilities
66
- def cli_utils
67
- [ 'git' ]
68
- end
69
-
70
- end
71
- end
@@ -1,68 +0,0 @@
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
- # scm provider facade
21
- class ScmProvider
22
-
23
- # Initializes the scm provider
24
- #
25
- # @param env [TaskExecutionEnvironment] env for the commands to be executed in
26
- # @param scm [Symbol] the scm provider to user
27
- def initialize(env, scm)
28
- raise ArgumentError, 'env must be a TaskExecutionEnvironment' unless env.is_a?(TaskExecutionEnvironment)
29
-
30
- @env = env
31
- @real_provider = nil
32
-
33
- if scm == :git
34
- @real_provider = GitScmProvider.new(env)
35
- end
36
- end
37
-
38
- # Checks out repository code from a system and switches to the given branch
39
- #
40
- # @param url [String] the repository location
41
- # @param local_dir [String] path to the working copy
42
- # @param branch [String] the branch to check out
43
- def checkout_from_remote(url, local_dir, branch)
44
- @real_provider.checkout_from_remote(url, local_dir, branch)
45
- end
46
-
47
- # Returns the current revision of the working copy
48
- #
49
- # @return [String] the current revision of the working copy
50
- def scm_files
51
- @real_provider.scm_files
52
- end
53
-
54
- # Returns scm files to be executed in the deployment process
55
- #
56
- # @return [Array] array of scm control files
57
- def cli_utils
58
- @real_provider.cli_utils
59
- end
60
-
61
- # Returns the scm tools that have to be installed on specific systems
62
- #
63
- # @return [Array] array of utilities
64
- def revision
65
- @real_provider.revision
66
- end
67
- end
68
- end
@@ -1,99 +0,0 @@
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
- Avocado::Deployment.configure do
20
-
21
- task :check_local_tools, before: :deploy, scope: :local, visibility: :private do
22
- check_util_availability [ 'tar' ].concat(@scm.cli_utils)
23
- end
24
-
25
- task :check_remote_system, before: :deploy, scope: :remote, visibility: :private do
26
- check_util_availability [ 'tar' ]
27
- end
28
-
29
- task :check_temp_existance, visibility: :private, after: :deploy, scope: :local do
30
- if File.exist?('.avocado-tmp')
31
- raise RuntimeError, 'The avocado tmp directory (.avocado-tmp) does already exist. That may indicate that another deployment is already running.'
32
- end
33
- end
34
-
35
- task :switch_to_temp_dir, visibility: :private, after: :check_temp_existance, scope: :local do
36
- command "mkdir .avocado-tmp/"
37
- chdir(".avocado-tmp/")
38
- end
39
-
40
- task :checkout_from_scm, visibility: :private, after: :switch_to_temp_dir, scope: :local do
41
- @scm.checkout_from_remote(get(:repo_url), 'working-copy', get(:branch))
42
- end
43
-
44
- task :get_scm_info, visibility: :private, after: :checkout_from_scm, scope: :local do
45
- chdir("working-copy/")
46
-
47
- set(:revision, @scm.revision)
48
-
49
- chdir("../")
50
- end
51
-
52
- task :delete_ignored_files, visibility: :private, after: :get_scm_info, scope: :local do
53
- if get(:ignore_files).concat(@scm.scm_files).size > 0
54
- chdir("working-copy/")
55
- command "rm -rfv #{get(:ignore_files).concat(@scm.scm_files).join(' ')}"
56
- chdir("../")
57
- end
58
- end
59
-
60
- task :create_revision_file, visibility: :private, after: :delete_ignored_files, scope: :local do
61
- chdir("working-copy/")
62
- command "echo '#{get(:revision)}' > REVISION"
63
- chdir("../")
64
- end
65
-
66
- task :create_deployment_tarball, visibility: :private, after: :create_revision_file, scope: :local do
67
- chdir("working-copy/")
68
- command "tar cvfz ../deploy.tar.gz ."
69
- chdir("../")
70
- end
71
-
72
- task :upload, visibility: :private, after: :create_deployment_tarball, scope: :local do
73
- targets.each_pair do |key, target|
74
- copy_to_target(target, 'deploy.tar.gz', '/tmp/deploy.tar.gz')
75
- end
76
- end
77
-
78
- task :create_deploy_dir, visibility: :private, after: :upload, scope: :remote do
79
- command "if [ ! -d '#{get(:deploy_dir)}' ]; then mkdir -p #{get(:deploy_dir)}; fi"
80
- end
81
-
82
- task :unpack, visibility: :private, after: :create_deploy_dir, scope: :remote do
83
- command "tar xvfz /tmp/deploy.tar.gz -C #{get(:deploy_dir)}/"
84
- end
85
-
86
- task :cleanup_remote, visibility: :private, after: :unpack, scope: :remote do
87
- command "rm /tmp/deploy.tar.gz"
88
- end
89
-
90
- task :log_deployment, visibility: :private, after: :cleanup_remote, scope: :remote do
91
- command "echo '[#{ Time.now.strftime('%Y-%m-%d %H-%M-%S')}] revision #{get(:revision)} deployed by #{ENV['USER']}' >> #{get(:log_file)}"
92
- end
93
-
94
- task :cleanup_local, visibility: :private, after: :cleanup_remote, scope: :local do
95
- chdir("../")
96
- command "rm -rf .avocado-tmp"
97
- end
98
-
99
- end
@@ -1,127 +0,0 @@
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 LocalTaskExecutionEnvironment < TaskExecutionEnvironment
21
-
22
- # Initialized the environment
23
- #
24
- # @param config [Hash] deployment configuration
25
- def initialize(config)
26
- super
27
-
28
- @dir = Dir.pwd
29
- end
30
-
31
- # Checks, if all utilities are available for the deployment process
32
- # to be executed
33
- #
34
- # @param utils [Array] array with utilities to check
35
- def check_util_availability(utils)
36
- super(utils, 'locally')
37
- end
38
-
39
- # Changes the directory for commands to be executed in
40
- #
41
- # @param dir [String] the directory to change to
42
- def chdir(dir)
43
- log.debug "changing directory [#{dir.yellow}] " + "locally".cyan
44
-
45
- Dir.chdir(dir)
46
- @dir = Dir.pwd
47
- end
48
-
49
- # Returns the current working directory
50
- #
51
- # @return [String] current working directory
52
- def cwd
53
- @dir
54
- end
55
-
56
- # Returns all target systems to deploy to
57
- #
58
- # @return [Hash] hash of target systems
59
- def targets
60
- Avocado::Deployment.instance.config.targets
61
- end
62
-
63
- # Copies a file to a remote system (= target)
64
- #
65
- # @param target [Target] the target system to deploy to
66
- # @param file [String] the local file to upload
67
- # @param remote [String] path on the remote system
68
- def copy_to_target(target, file, remote)
69
- log = Avocado::Deployment.instance.log
70
-
71
- log.info "started upload of file #{file} to #{target.name}"
72
-
73
- Net::SSH.start(
74
- target.config[:host],
75
- target.config[:user]
76
- ) do |session|
77
- session.scp.upload!(file, remote, :recursive => true) do |ch, name, sent, total|
78
- percentage = 0
79
-
80
- begin
81
- percentage = (sent.to_f * 100 / total.to_f).to_i
82
- rescue Exception => e
83
- Avocado::Deployment.instance.handle_abort(e)
84
- end
85
-
86
- #log.info "\r#{name}: #{percentage}%"
87
- end
88
- end
89
-
90
- log.info "upload completed"
91
- end
92
-
93
- # Executes a command locally in the current directory
94
- #
95
- # @param cmd [String] the command to execute
96
- # @return [CommandExecutionResult] result of the command exection
97
- def command(cmd)
98
- log = Avocado::Deployment.instance.log
99
-
100
- log.info "Executing [" + cmd.yellow + "] " + "locally".cyan
101
-
102
- result = Avocado::CommandExecutionResult.new
103
-
104
- begin
105
- stdout, stderr, status = ::Open3.capture3(cmd, :chdir => cwd())
106
-
107
- result.stdin = cmd
108
- result.stdout = stdout
109
- result.stderr = stderr
110
- result.retval = status.exitstatus
111
-
112
- if result.stdout.nil? == false && result.stdout.empty? == false
113
- log.debug "Stdout: " + result.stdout.green
114
- end
115
-
116
- if result.stderr.nil? == false && result.stderr.empty? == false
117
- log.debug "Stderr: " + result.stderr.red
118
- end
119
- rescue Exception => e
120
- handle_abort e
121
- end
122
-
123
- result
124
- end
125
-
126
- end
127
- end
@@ -1,112 +0,0 @@
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 RemoteTaskExecutionEnvironment < TaskExecutionEnvironment
21
-
22
- attr_accessor :config
23
-
24
- # Creates a connection between the local and the remote system over ssh
25
- def establish_connection
26
- Avocado::Deployment.instance.log.info "connecting to #{get(:user)}@#{get(:host)}..."
27
-
28
- begin
29
- @session = ::Net::SSH.start(get(:host), get(:user))
30
- rescue ::Net::SSH::AuthenticationFailed => e
31
- handle_abort e
32
- end
33
- end
34
-
35
- # Checks, if all utilities are available for the deployment process
36
- # to be executed
37
- #
38
- # @param utils [Array] array with utilities to check
39
- def check_util_availability(utils)
40
- super(utils, 'remotely')
41
- end
42
-
43
- # Executes a command via ssh
44
- #
45
- # @param ssh [Net::SSH::Connection::Session] ssh session
46
- # @param command [String] the command to execute
47
- def ssh_exec!(ssh, command)
48
- stdout_data = ""
49
- stderr_data = ""
50
- exit_code = nil
51
- exit_signal = nil
52
- ssh.open_channel do |channel|
53
- channel.exec(command) do |ch, success|
54
- unless success
55
- abort "FAILED: couldn't execute command (ssh.channel.exec)"
56
- end
57
- channel.on_data do |ch,data|
58
- stdout_data+=data
59
- end
60
-
61
- channel.on_extended_data do |ch,type,data|
62
- stderr_data+=data
63
- end
64
-
65
- channel.on_request("exit-status") do |ch,data|
66
- exit_code = data.read_long
67
- end
68
-
69
- channel.on_request("exit-signal") do |ch, data|
70
- exit_signal = data.read_long
71
- end
72
- end
73
- end
74
- ssh.loop
75
-
76
- result = Avocado::CommandExecutionResult.new
77
- result.stdin = command
78
- result.stdout = stdout_data
79
- result.stderr = stderr_data
80
- result.retval = exit_code
81
-
82
- result
83
- end
84
-
85
- # Executes a command on the remote system
86
- #
87
- # @param cmd [String] the command to execute
88
- # @return [CommandExecutionResult] result of the command exection
89
- def command(cmd)
90
- Avocado::Deployment.instance.log.info "Executing [" + cmd.yellow + "] on remote " + get(:ssh_host).cyan
91
-
92
- result = Avocado::CommandExecutionResult.new
93
-
94
- begin
95
- result = ssh_exec!(@session, cmd)
96
-
97
- if result.stdout.nil? == false && result.stdout.empty? == false
98
- Avocado::Deployment.instance.log.debug "Stdout@#{get(:host)}: ".cyan + result.stdout.green
99
- end
100
-
101
- if result.stderr.nil? == false && result.stderr.empty? == false
102
- Avocado::Deployment.instance.log.debug "Stderr@#{get(:host)}: ".cyan + result.stderr.red
103
- end
104
- rescue Exception => e
105
- handle_abort e
106
- end
107
-
108
- result
109
- end
110
-
111
- end
112
- end