avodeploy 0.4.2 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,13 +17,13 @@
17
17
  =end
18
18
 
19
19
  AvoDeploy::Deployment.configure do
20
-
21
- task :deploy, visibility: :public do
22
- # stub for cli calls
23
- end
24
20
 
25
- task :check_ssh_connection, before: :deploy, scope: :remote, visibility: :private do
26
- log.info "checking ssh connection"
27
- end
21
+ task :deploy, visibility: :public do
22
+ # stub for cli calls
23
+ end
24
+
25
+ task :check_ssh_connection, before: :deploy, scope: :remote, visibility: :private do
26
+ log.info 'checking ssh connection'
27
+ end
28
28
 
29
29
  end
@@ -18,84 +18,104 @@
18
18
 
19
19
  AvoDeploy::Deployment.configure do
20
20
 
21
- task :check_targets, before: :deploy do
22
- raise RuntimeError, 'No target systems are configured' if targets.empty?
23
- end
24
-
25
- task :check_local_tools, before: :deploy do
26
- check_util_availability [ 'tar' ].concat(@scm.cli_utils)
27
- end
28
-
29
- task :check_remote_system, before: :deploy do
30
- check_util_availability [ 'tar' ]
31
- end
32
-
33
- task :check_temp_existance, after: :deploy do
34
- if File.exist?('.avocado-tmp')
35
- raise RuntimeError, 'The avocado tmp directory (.avocado-tmp) does already exist. That may indicate that another deployment is already running.'
36
- end
37
- end
38
-
39
- task :switch_to_temp_dir, after: :check_temp_existance do
40
- command "mkdir .avocado-tmp/"
41
- chdir ".avocado-tmp/"
42
- end
43
-
44
- task :checkout_from_scm, after: :switch_to_temp_dir do
45
- @scm.checkout_from_remote(get(:repo_url), 'working-copy', get(:branch))
46
- end
47
-
48
- task :chdir_to_working_copy, after: :checkout_from_scm do
49
- chdir "working-copy/"
50
- end
51
-
52
- task :get_scm_info, after: :chdir_to_working_copy do
53
- set :revision, @scm.revision
54
- end
55
-
56
- task :delete_ignored_files, after: :get_scm_info do
57
- files_to_delete = [ 'Avofile' ].concat(get(:ignore_files)).concat(@scm.scm_files)
58
-
59
- command "rm -rfv #{files_to_delete.join(' ')}"
60
- end
61
-
62
- task :create_revision_file, after: :delete_ignored_files do
63
- command "echo '#{get(:revision)}' > REVISION"
64
- end
65
-
66
- task :create_deployment_tarball, after: :create_revision_file do
67
- command "tar cvfz ../deploy.tar.gz ."
68
- end
69
-
70
- task :switch_to_parent_dir, after: :create_deployment_tarball do
71
- chdir "../"
72
- end
73
-
74
- task :upload, after: :switch_to_parent_dir do
75
- targets.each_pair do |key, target|
76
- copy_to_target(target, 'deploy.tar.gz', '/tmp/deploy.tar.gz')
77
- end
78
- end
79
-
80
- task :create_deploy_dir, after: :upload, scope: :remote do
81
- command "if [ ! -d '#{get(:deploy_dir)}' ]; then mkdir -p #{get(:deploy_dir)}; fi"
82
- end
83
-
84
- task :unpack, after: :create_deploy_dir, scope: :remote do
85
- command "tar xvfz /tmp/deploy.tar.gz -C #{get(:deploy_dir)}/"
86
- end
87
-
88
- task :cleanup_remote, after: :unpack, scope: :remote do
89
- command "rm /tmp/deploy.tar.gz"
90
- end
91
-
92
- task :log_deployment, after: :cleanup_remote, scope: :remote do
93
- command "echo '[#{Time.now.strftime('%Y-%m-%d %H-%M-%S')}] revision #{get(:revision)} deployed by #{ENV['USER']}' >> #{get(:log_file)}"
94
- end
95
-
96
- task :cleanup_local, after: :cleanup_remote do
97
- chdir "../"
98
- command "rm -rf .avocado-tmp"
99
- end
21
+ inherit_strategy :base
22
+
23
+ task :check_targets, before: :deploy do
24
+ raise RuntimeError, 'No target systems are configured' if targets.empty?
25
+ end
26
+
27
+ task :check_local_tools, before: :deploy do
28
+ check_util_availability ['tar'].concat(@scm.cli_utils)
29
+ end
30
+
31
+ task :check_remote_system, before: :deploy, scope: :remote do
32
+ res = command 'uname -a'
33
+
34
+ if res.stdout.include?('Linux') == false
35
+ raise RuntimeError, 'Only linux target systems are supported right now.'
36
+ end
37
+
38
+ check_util_availability ['tar']
39
+ end
40
+
41
+ task :check_temp_existance, after: :deploy do
42
+ if File.exist?('.avocado-tmp')
43
+ raise RuntimeError, 'The avocado tmp directory (.avocado-tmp) does already exist. That may indicate that another deployment is already running.'
44
+ end
45
+ end
46
+
47
+ task :switch_to_temp_dir, after: :check_temp_existance do
48
+ command 'mkdir .avocado-tmp/'
49
+ chdir '.avocado-tmp/'
50
+ end
51
+
52
+ task :checkout_from_scm, after: :switch_to_temp_dir do
53
+ tag = nil
54
+
55
+ if @options.nil? == false && @options[:tag].nil? == false
56
+ tag = @options[:tag]
57
+ end
58
+
59
+ if get(:force_tag) && tag.nil?
60
+ raise RuntimeError, 'Deployment requires a tag but none was submitted'
61
+ end
62
+
63
+ @scm.checkout_from_remote(get(:repo_url), 'working-copy', get(:branch), tag)
64
+ end
65
+
66
+ task :chdir_to_working_copy, after: :checkout_from_scm do
67
+ chdir 'working-copy/'
68
+ end
69
+
70
+ task :get_scm_info, after: :chdir_to_working_copy do
71
+ set :revision, @scm.revision
72
+ end
73
+
74
+ task :create_revision_file, after: :get_scm_info do
75
+ command "echo '#{get(:revision)}' > REVISION"
76
+ end
77
+
78
+ task :create_deployment_tarball, after: :create_revision_file do
79
+ files_to_delete = ['Avofile'].concat(get(:ignore_files)).concat(@scm.scm_files)
80
+
81
+ exclude_param = ''
82
+
83
+ files_to_delete.each do |file|
84
+ exclude_param += " --exclude='^#{file}$'"
85
+ end
86
+
87
+ command "tar cfz ../deploy.tar.gz #{exclude_param} ."
88
+ end
89
+
90
+ task :switch_to_parent_dir, after: :create_deployment_tarball do
91
+ chdir '../'
92
+ end
93
+
94
+ task :upload, after: :switch_to_parent_dir do
95
+ targets.each_pair do |key, target|
96
+ copy_to_target(target, 'deploy.tar.gz', '/tmp/deploy.tar.gz')
97
+ end
98
+ end
99
+
100
+ task :create_deploy_dir, after: :upload, scope: :remote do
101
+ command "if [ ! -d '#{get(:deploy_dir)}' ]; then mkdir -p #{get(:deploy_dir)}; fi"
102
+ end
103
+
104
+ task :unpack, after: :create_deploy_dir, scope: :remote do
105
+ command "tar xvfz /tmp/deploy.tar.gz -C #{get(:deploy_dir)}/"
106
+ end
107
+
108
+ task :cleanup_remote, after: :unpack, scope: :remote do
109
+ command 'rm /tmp/deploy.tar.gz'
110
+ end
111
+
112
+ task :log_deployment, after: :cleanup_remote, scope: :remote do
113
+ command "echo '[#{Time.now.strftime('%Y-%m-%d %H-%M-%S')}] revision #{get(:revision)} deployed by #{ENV['USER']}' >> #{get(:log_file)}"
114
+ end
115
+
116
+ task :cleanup_local, after: :cleanup_remote do
117
+ chdir '../'
118
+ command 'rm -rf .avocado-tmp'
119
+ end
100
120
 
101
121
  end
@@ -0,0 +1,86 @@
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
+ AvoDeploy::Deployment.configure do
20
+
21
+ inherit_strategy :local_copy
22
+
23
+ task :get_deployed_revision, after: :chdir_to_working_copy, scope: :remote do
24
+ res = command "cat #{get(:deploy_dir)}/REVISION"
25
+
26
+ if get(:deployed_revisions).nil?
27
+ deployed_revisions = {}
28
+ else
29
+ deployed_revisions = get(:deployed_revisions)
30
+ end
31
+
32
+ revision = nil
33
+
34
+ if res.retval == 0
35
+ # file exists
36
+ revision = res.stdout.lines.first.strip
37
+ end
38
+
39
+ deployed_revisions[get(:name)] = revision
40
+ set(:deployed_revisions, deployed_revisions)
41
+ end
42
+
43
+ task :create_deployment_tarball, after: :create_revision_file do
44
+ new_revision = get(:revision)
45
+
46
+ get(:deployed_revisions).each_pair do |target_name, deployed_revision|
47
+ # determine, which files to exclude
48
+ files_to_delete = ['Avofile'].concat(get(:ignore_files)).concat(@scm.scm_files)
49
+
50
+ exclude_param = ''
51
+
52
+ files_to_delete.each do |file|
53
+ exclude_param += " --exclude='^#{file}$'"
54
+ end
55
+
56
+ # create deployment archive
57
+ if deployed_revision.nil?
58
+ # create full deployment archive
59
+ command "tar -czvf ../deploy_#{target_name.to_s}.tar.gz #{exclude_param} ."
60
+ else
61
+ # create partial deployment archive
62
+ diff_files = @scm.diff_files_between_revisions(deployed_revision, new_revision)
63
+
64
+ # always include the revision file
65
+ # UPDATE: not longer needed because REVISION is in the unknown_files array anyway
66
+ #diff_files << 'REVISION'
67
+
68
+ # include unknown files
69
+ unknown_files = @scm.unknown_files_in_workdir
70
+
71
+ File.open("../files_#{target_name.to_s}.txt", 'w') do |f|
72
+ f << diff_files.concat(unknown_files).join("\n")
73
+ end
74
+
75
+ command "tar cvfz ../deploy_#{target_name.to_s}.tar.gz -T ../files_#{target_name.to_s}.txt #{exclude_param}"
76
+ end
77
+ end
78
+ end
79
+
80
+ task :upload, after: :switch_to_parent_dir do
81
+ targets.each_pair do |key, target|
82
+ copy_to_target(target, "deploy_#{target.name.to_s}.tar.gz", '/tmp/deploy.tar.gz')
83
+ end
84
+ end
85
+
86
+ end
@@ -17,35 +17,36 @@
17
17
  =end
18
18
 
19
19
  module AvoDeploy
20
- class Target
21
-
22
- attr_reader :name
23
- attr_reader :config
24
-
25
- # Initializes the deployment target
26
- #
27
- # @param name [Symbol] target name
28
- # @param config [Hash] target config
29
- def initialize(name, config)
30
- @name = name
31
- @config = default_config.merge(config)
32
- @config[:name] = name
33
- end
34
-
35
- private
36
- # Sets up the config defaults
37
- #
38
- # @return [Hash] config defaults
39
- def default_config
40
- {
41
- :name => '',
42
- :host => nil,
43
- :user => 'root',
44
- :auth => :pubkey,
45
- :deploy_dir => '/var/www/',
46
- :log_file => '/var/www/deploy.log',
47
- }
48
- end
49
-
50
- end
20
+ class Target
21
+
22
+ attr_reader :name
23
+ attr_reader :config
24
+
25
+ # Initializes the deployment target
26
+ #
27
+ # @param name [Symbol] target name
28
+ # @param config [Hash] target config
29
+ def initialize(name, config)
30
+ @name = name
31
+ @config = default_config.merge(config)
32
+ @config[:name] = name
33
+ end
34
+
35
+ private
36
+ # Sets up the config defaults
37
+ #
38
+ # @return [Hash] config defaults
39
+ def default_config
40
+ {
41
+ :name => '',
42
+ :host => nil,
43
+ :port => 22,
44
+ :user => 'root',
45
+ :auth => :pubkey,
46
+ :deploy_dir => '/var/www/',
47
+ :log_file => '/var/www/deploy.log',
48
+ }
49
+ end
50
+
51
+ end
51
52
  end
@@ -17,111 +17,116 @@
17
17
  =end
18
18
 
19
19
  module AvoDeploy
20
- module Task
21
- class LocalTaskExecutionEnvironment < TaskExecutionEnvironment
22
-
23
- # Initialized the environment
24
- #
25
- # @param config [Hash] deployment configuration
26
- def initialize(config)
27
- super
28
-
29
- @dir = Dir.pwd
30
- end
31
-
32
- # Checks, if all utilities are available for the deployment process
33
- # to be executed
34
- #
35
- # @param utils [Array] array with utilities to check
36
- def check_util_availability(utils)
37
- super(utils, 'locally')
38
- end
39
-
40
- # Changes the directory for commands to be executed in
41
- #
42
- # @param dir [String] the directory to change to
43
- def chdir(dir)
44
- log.debug "changing directory [#{dir.yellow}] " + "locally".cyan
45
-
46
- Dir.chdir(dir)
47
- @dir = Dir.pwd
48
- end
49
-
50
- # Returns the current working directory
51
- #
52
- # @return [String] current working directory
53
- def cwd
54
- @dir
55
- end
56
-
57
- # Returns all target systems to deploy to
58
- #
59
- # @return [Hash] hash of target systems
60
- def targets
61
- AvoDeploy::Deployment.instance.config.targets
62
- end
63
-
64
- # Copies a file to a remote system (= target)
65
- #
66
- # @param target [Target] the target system to deploy to
67
- # @param file [String] the local file to upload
68
- # @param remote [String] path on the remote system
69
- def copy_to_target(target, file, remote)
70
- log = AvoDeploy::Deployment.instance.log
71
-
72
- log.info "started upload of file #{file} to #{target.name}"
73
-
74
- Net::SSH.start(
75
- target.config[:host],
76
- target.config[:user]
77
- ) do |session|
78
- session.scp.upload!(file, remote, :recursive => true) do |ch, name, sent, total|
79
- percentage = 0
80
-
81
- begin
82
- percentage = (sent.to_f * 100 / total.to_f).to_i
83
- rescue Exception => e
84
- AvoDeploy::Deployment.instance.handle_abort(e)
85
- end
86
- end
87
- end
88
-
89
- log.info "upload completed"
90
- end
91
-
92
- # Executes a command locally in the current directory
93
- #
94
- # @param cmd [String] the command to execute
95
- # @return [CommandExecutionResult] result of the command exection
96
- def command(cmd)
97
- log = AvoDeploy::Deployment.instance.log
98
-
99
- log.info "Executing [" + cmd.yellow + "] " + "locally".cyan
100
-
101
- result = AvoDeploy::CommandExecutionResult.new
102
-
103
- begin
104
- stdout, stderr, status = ::Open3.capture3(cmd, :chdir => cwd())
105
-
106
- result.stdin = cmd
107
- result.stdout = stdout
108
- result.stderr = stderr
109
- result.retval = status.exitstatus
110
-
111
- if result.stdout.nil? == false && result.stdout.empty? == false
112
- log.debug "Stdout: " + result.stdout.green
113
- end
114
-
115
- if result.stderr.nil? == false && result.stderr.empty? == false
116
- log.debug "Stderr: " + result.stderr.red
117
- end
118
- rescue Exception => e
119
- handle_abort e
120
- end
121
-
122
- result
123
- end
124
-
125
- end
126
- end
20
+ module Task
21
+ class LocalTaskExecutionEnvironment < TaskExecutionEnvironment
22
+
23
+ # Initialized the environment
24
+ #
25
+ # @param config [Hash] deployment configuration
26
+ def initialize(config)
27
+ super
28
+
29
+ @dir = Dir.pwd
30
+ end
31
+
32
+ # Checks, if all utilities are available for the deployment process
33
+ # to be executed
34
+ #
35
+ # @param utils [Array] array with utilities to check
36
+ def check_util_availability(utils)
37
+ super(utils, 'locally')
38
+ end
39
+
40
+ # Changes the directory for commands to be executed in
41
+ #
42
+ # @param dir [String] the directory to change to
43
+ def chdir(dir)
44
+ log.debug "changing directory [#{dir.yellow}] " + "locally".cyan
45
+
46
+ Dir.chdir(dir)
47
+ @dir = Dir.pwd
48
+ end
49
+
50
+ # Returns the current working directory
51
+ #
52
+ # @return [String] current working directory
53
+ def cwd
54
+ @dir
55
+ end
56
+
57
+ # Returns all target systems to deploy to
58
+ #
59
+ # @return [Hash] hash of target systems
60
+ def targets
61
+ AvoDeploy::Deployment.instance.config.targets
62
+ end
63
+
64
+ # Copies a file to a remote system (= target)
65
+ #
66
+ # @param target [Target] the target system to deploy to
67
+ # @param file [String] the local file to upload
68
+ # @param remote [String] path on the remote system
69
+ def copy_to_target(target, file, remote)
70
+ log = AvoDeploy::Deployment.instance.log
71
+
72
+ log.info "started upload of file #{file} to #{target.name}"
73
+
74
+ Net::SSH.start(
75
+ target.config[:host],
76
+ target.config[:user],
77
+ {
78
+ :port => target.config[:port]
79
+ }
80
+ ) do |session|
81
+ session.scp.upload!(file, remote, :recursive => true) do |ch, name, sent, total|
82
+ percentage = 0
83
+
84
+ begin
85
+ percentage = (sent.to_f * 100 / total.to_f).to_i
86
+ rescue Exception => e
87
+ AvoDeploy::Deployment.instance.handle_abort(e)
88
+ end
89
+ end
90
+ end
91
+
92
+ log.info "upload completed"
93
+ end
94
+
95
+ # Executes a command locally in the current directory
96
+ #
97
+ # @param cmd [String] the command to execute
98
+ # @return [CommandExecutionResult] result of the command exection
99
+ def command(cmd)
100
+ log = AvoDeploy::Deployment.instance.log
101
+
102
+ log.info "Executing [" + cmd.yellow + "] " + "locally".cyan
103
+
104
+ result = AvoDeploy::CommandExecutionResult.new
105
+
106
+ begin
107
+ stdout, stderr, status = ::Open3.capture3(cmd, :chdir => cwd())
108
+
109
+ result.stdin = cmd
110
+ result.stdout = stdout
111
+ result.stderr = stderr
112
+ result.retval = status.exitstatus
113
+
114
+ if result.stdout.nil? == false && result.stdout.empty? == false
115
+ log.debug 'Stdout: ' + result.stdout.green
116
+ end
117
+
118
+ if result.stderr.nil? == false && result.stderr.empty? == false
119
+ log.debug 'Stderr: ' + result.stderr.red
120
+ end
121
+
122
+ log.debug 'Retval: ' + result.retval.to_s
123
+ rescue Exception => e
124
+ handle_abort e
125
+ end
126
+
127
+ result
128
+ end
129
+
130
+ end
131
+ end
127
132
  end