avst-cloud 0.1.7

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.
@@ -0,0 +1,56 @@
1
+ # Copyright 2015 Adaptavist.com Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative './cloud_server.rb'
16
+
17
+ module AvstCloud
18
+ class AwsServer < AvstCloud::CloudServer
19
+
20
+ def stop
21
+ if @server
22
+ logger.debug "Stopping #{@server_name}"
23
+ @server.stop
24
+ wait_for_state() {|serv| serv.state == 'stopped'}
25
+ logger.debug "[DONE]\n\n"
26
+ logger.debug "Server #{@server_name} stopped...".green
27
+ else
28
+ raise "Server #{@server_name} does not exist!".red
29
+ end
30
+ end
31
+
32
+ def start
33
+ if @server
34
+ logger.debug "Starting #{@server_name}"
35
+ @server.start
36
+ wait_for_state() {|serv| serv.ready?}
37
+ logger.debug "[DONE]\n\n"
38
+ logger.debug "Server #{@server_name} started...".green
39
+ else
40
+ raise "Server #{@server_name} does not exist!".red
41
+ end
42
+ end
43
+
44
+ def destroy
45
+ if @server
46
+ logger.debug "Killing #{@server_name}"
47
+ @server.destroy
48
+ wait_for_state() {|serv| serv.state == 'terminated'}
49
+ logger.debug "Server #{@server_name} destroyed...".green
50
+ else
51
+ raise "Server #{@server_name} does not exist!".red
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,39 @@
1
+ # Copyright 2015 Adaptavist.com Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative './logging.rb'
16
+
17
+ module AvstCloud
18
+ class CloudConnection
19
+ include Logging
20
+ attr_accessor :connection, :provider, :provider_user, :provider_pass
21
+
22
+ def initialize(provider, provider_user, provider_pass)
23
+ @provider = provider
24
+ @provider_access_user = provider_user
25
+ @provider_access_pass = provider_pass
26
+ end
27
+
28
+ # Abstract classes to be implemented per provider
29
+ UNIMPLEMENTED="Unimplemented..."
30
+
31
+ def server(server_name, root_user, root_password, os=nil)
32
+ raise UNIMPLEMENTED
33
+ end
34
+
35
+ def list_known_servers
36
+ raise UNIMPLEMENTED
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,89 @@
1
+ # Copyright 2015 Adaptavist.com Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative './logging.rb'
16
+ require_relative './task.rb'
17
+
18
+ module AvstCloud
19
+ class CloudServer
20
+ include Logging
21
+ attr_accessor :server, :server_name, :ip_address, :access_user, :access_password
22
+
23
+ def initialize(server, server_name, ip_address, access_user, access_password)
24
+ @server = server
25
+ @ip_address = ip_address
26
+ @server_name = server_name
27
+ @access_user = access_user
28
+ @access_password = access_password
29
+ end
30
+
31
+ def bootstrap(pre_upload_commands, custom_file_uploads, post_upload_commands, remote_server_debug, debug_structured_log)
32
+ logger.debug "Bootstrapping #{server_name}...".green
33
+ run_tasks([AvstCloud::WaitUntilReady.new])
34
+ disable_tty_task = AvstCloud::DisableRequireTty.new(@access_user)
35
+ pre_upload_commands_tasks = AvstCloud::SshCommandTask.new(pre_upload_commands, remote_server_debug, debug_structured_log)
36
+ custom_file_uploads_tasks = AvstCloud::ScpTask.new(custom_file_uploads)
37
+ post_upload_commands_tasks = AvstCloud::SshCommandTask.new(post_upload_commands, remote_server_debug, debug_structured_log)
38
+ run_tasks([disable_tty_task, pre_upload_commands_tasks, custom_file_uploads_tasks, post_upload_commands_tasks])
39
+ logger.debug "Bootstrap done. You can connect to server as #{@access_user} on #{@ip_address}"
40
+ end
41
+
42
+ def provision(git, branch, server_tmp_folder, reference, custom_provisioning_commands, puppet_runner, puppet_runner_prepare, destination_folder)
43
+ logger.debug "Provisioning #{@server_name}..."
44
+ provision_task = AvstCloud::CapistranoDeploymentTask.new(git, branch, server_tmp_folder, reference, custom_provisioning_commands, puppet_runner, puppet_runner_prepare, destination_folder)
45
+ run_tasks([AvstCloud::WaitUntilReady.new, provision_task])
46
+ logger.debug "Provisioning done. You can connect to server on #{@ip_address}"
47
+ end
48
+
49
+ def post_provisioning_cleanup(custom_commands, os, remote_server_debug, server_tmp_folder)
50
+ logger.debug "Cleaning up after provisioning #{server_name}..."
51
+ custom_cleanup_commands = AvstCloud::SshCommandTask.new(custom_commands, remote_server_debug, true)
52
+ run_tasks([AvstCloud::WaitUntilReady.new, AvstCloud::PostProvisionCleanup.new(os, remote_server_debug, server_tmp_folder), custom_cleanup_commands])
53
+ logger.debug "Post provisioning cleanup done. You can connect to server as #{@access_user} on #{@ip_address}"
54
+ end
55
+
56
+ def run_tasks(tasks)
57
+ Array(tasks).each do |task|
58
+ task.execute self
59
+ end
60
+ end
61
+
62
+ def status
63
+ @server.state
64
+ end
65
+
66
+ def wait_for_state(&cond)
67
+ logger.debug "Waiting for state change...".yellow
68
+ @server.wait_for(600, 5) do
69
+ print "."
70
+ STDOUT.flush
71
+ cond.call(self)
72
+ end
73
+ end
74
+
75
+ # Abstract classes to be implemented per provider
76
+ UNIMPLEMENTED="Unimplemented..."
77
+ def stop
78
+ raise UNIMPLEMENTED
79
+ end
80
+
81
+ def start
82
+ raise UNIMPLEMENTED
83
+ end
84
+
85
+ def destroy
86
+ raise UNIMPLEMENTED
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,36 @@
1
+ # Copyright 2015 Adaptavist.com Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'logger'
16
+
17
+ module Logging
18
+ def self.included(base)
19
+ class << base
20
+ def logger
21
+ @logger ||= Logger.new($stdout)
22
+ end
23
+
24
+ def logger=(logger)
25
+ @logger = logger
26
+ end
27
+ end
28
+ end
29
+
30
+ def logger
31
+ self.class.logger
32
+ end
33
+ def logger=(logger)
34
+ @logger = logger
35
+ end
36
+ end
@@ -0,0 +1,141 @@
1
+ # Copyright 2015 Adaptavist.com Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative './cloud_connection.rb'
16
+
17
+ module AvstCloud
18
+
19
+ class RackspaceConnection < AvstCloud::CloudConnection
20
+
21
+ attr_accessor :region
22
+
23
+ def initialize(provider_access_user, provider_access_pass, region=:lon)
24
+ super('rackspace',provider_access_user, provider_access_pass)
25
+ @region = region
26
+ end
27
+
28
+ def server(server_name, root_user, root_password, os=nil)
29
+ server = find_fog_server(server_name)
30
+ if !root_user
31
+ root_user = "root"
32
+ end
33
+ AvstCloud::RackspaceServer.new(server, server_name, server.public_ip_address, root_user, root_password)
34
+ end
35
+
36
+ def create_server(server_name, image_id, flavor_id='4')
37
+ server_number, os="ubuntu14"
38
+
39
+ logger.debug "Creating Rackspace server:"
40
+ logger.debug "server_name - #{server_name}"
41
+ logger.debug "flavor_id - #{flavor_id}"
42
+ logger.debug "image_id - #{image_id}"
43
+
44
+ unless server_name and image_id
45
+ raise "Please provide server_name, image_id and flavor_id"
46
+ end
47
+
48
+ # Check existing server
49
+ existing_server = find_fog_server(server_name, false)
50
+ if existing_server && existing_server.state != 'SHUTOFF'
51
+ logger.debug "Server found in state: #{existing_server.state}"
52
+ raise "Server with the same name found!"
53
+ elsif existing_server && existing_server.state == 'SHUTOFF'
54
+ logger.debug "Server found and is stopped, restarting it."
55
+ existing_server.reboot 'HARD'
56
+ result_server = AvstCloud::RackspaceServer.new(existing_server, server_name, nil, nil , nil)
57
+ result_server.wait_for_state() {|serv| serv.ready?}
58
+ logger.debug "[DONE]\n\n"
59
+ logger.debug "The server was successfully re-started.\n\n"
60
+ else
61
+ # create server
62
+ server = connect.servers.create :name => server_name,
63
+ :flavor_id => flavor_id,
64
+ :image_id => image_id
65
+ begin
66
+ result_server = AvstCloud::RackspaceServer.new(server, server_name, nil, nil , nil)
67
+ # Check every 5 seconds to see if server is in the active state (ready?).
68
+ # If the server has not been built in 5 minutes (600 seconds) an exception will be raised.
69
+ result_server.wait_for_state() {|serv| serv.ready?}
70
+ logger.debug "[DONE]\n\n"
71
+
72
+ logger.debug "The server has been successfully created, to login onto the server:\n\n"
73
+ logger.debug "\t ssh #{server.username}@#{server.public_ip_address}\n\n"
74
+
75
+ rescue Fog::Errors::TimeoutError
76
+ logger.debug "[TIMEOUT]\n\n"
77
+ logger.debug "This server is currently #{server.progress}% into the build process and is taking longer to complete than expected."
78
+ logger.debug "You can continute to monitor the build process through the web console at https://mycloud.rackspace.com/\n\n"
79
+ raise "Timeout while creating Rackspace server #{server_name}"
80
+ end
81
+ logger.debug "The #{server.username} password is #{server.password}\n\n"
82
+ end
83
+ result_server.access_user = server.username
84
+ result_server.access_password = server.password
85
+ result_server.ip_address = server.public_ip_address
86
+ result_server
87
+ end
88
+
89
+ def server_status(server_name)
90
+ server = find_fog_server(server_name, false)
91
+ if server
92
+ server.state
93
+ else
94
+ 'not_created'
95
+ end
96
+ end
97
+
98
+ def list_flavours
99
+ connect.flavors.each do |fl|
100
+ logger.debug fl.inspect
101
+ end
102
+ end
103
+
104
+ def list_images
105
+ connect.images.each do |im|
106
+ logger.debug im.inspect
107
+ end
108
+ end
109
+
110
+ # Returns list of servers from fog
111
+ def list_known_servers
112
+ connect.servers.all
113
+ end
114
+
115
+ def find_fog_server(server_name, should_fail=true)
116
+ serv = connect.servers.find{|serv| serv.name == server_name}
117
+ unless serv
118
+ if should_fail
119
+ logger.debug "Server not found for name: #{server_name}"
120
+ raise "Server not found for name: #{server_name}"
121
+ end
122
+ end
123
+ serv
124
+ end
125
+
126
+ private
127
+ def connect
128
+ unless @connection
129
+ logger.debug "Creating new connection to rackspace: #{@provider_user} #{@provider_pass} #{@region}"
130
+ @connection = Fog::Compute.new({
131
+ :provider => 'rackspace',
132
+ :rackspace_username => @provider_access_user,
133
+ :rackspace_api_key => @provider_access_pass,
134
+ :version => :v2, # Use Next Gen Cloud Servers
135
+ :rackspace_region => @region
136
+ })
137
+ end
138
+ @connection
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright 2015 Adaptavist.com Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative './cloud_server.rb'
16
+
17
+ module AvstCloud
18
+ class RackspaceServer < AvstCloud::CloudServer
19
+
20
+ def stop
21
+ if @server
22
+ logger.debug "Stopping #{@server_name}"
23
+
24
+ shutdown_command = AvstCloud::SshCommandTask.new(['shutdown -h now'])
25
+ run_tasks([AvstCloud::WaitUntilReady.new, shutdown_command])
26
+ logger.debug "Waiting for SHUTOFF state..."
27
+ wait_for_state() {|serv| serv.state == 'SHUTOFF'}
28
+ logger.debug "[DONE]\n\n"
29
+ logger.debug "Server #{@server_name} stopped...".green
30
+ else
31
+ raise "Server #{@server_name} does not exist!".red
32
+ end
33
+ end
34
+
35
+ def start
36
+ if @server
37
+ logger.debug "Starting #{@server_name}"
38
+ @server.reboot 'HARD'
39
+ logger.debug "Waiting for ACTIVE state..."
40
+ wait_for_state() {|serv| serv.ready?}
41
+ logger.debug "[DONE]\n\n"
42
+ logger.debug "Server #{@server_name} started...".green
43
+ else
44
+ raise "Server #{@server_name} does not exist!".red
45
+ end
46
+ end
47
+
48
+ def destroy
49
+ if @server
50
+ logger.debug "Killing #{@server_name}"
51
+ @server.destroy
52
+ logger.debug "Server #{@server_name} destroyed...".green
53
+ else
54
+ raise "Server #{@server_name} does not exist!".red
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,288 @@
1
+ # Copyright 2015 Adaptavist.com Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative './logging.rb'
16
+
17
+ module AvstCloud
18
+ class Task
19
+ include Logging
20
+ def initialize(debug = false)
21
+ @debug = debug
22
+ end
23
+ def execute(server)
24
+ raise 'Unimplemented...'
25
+ end
26
+ end
27
+
28
+ class SshTask < AvstCloud::Task
29
+ include Logging
30
+ def execute(server)
31
+ unless server.ip_address
32
+ logger.error 'Can not find host'.red
33
+ raise 'Can not find ip address, access_user or access_password'
34
+ end
35
+
36
+ unless server.access_user
37
+ logger.error 'Access user not found. Please provide username for this server.'.red
38
+ raise 'Access user not found. Please provide username for this server.'
39
+ end
40
+
41
+ unless server.access_password
42
+ logger.error 'Password not found. Please provide password or pem key for this server.'.red
43
+ raise 'Password not found. Please provide root_password in config. for this server.'
44
+ end
45
+
46
+ logger.debug "Using #{server.access_user}@#{server.ip_address} with #{server.access_password} to perform ssh task."
47
+ attempts = 1
48
+ success = false
49
+ max_attempts = 50
50
+ while attempts < max_attempts and !success
51
+ begin
52
+ Net::SSH.start(server.ip_address, server.access_user, :password => server.access_password, :keys => [server.access_password]) do |session|
53
+ ssh_command session
54
+ end
55
+ success = true
56
+ rescue Errno::ECONNREFUSED
57
+ logger.debug "Connection refused. Server may not have booted yet. Sleeping #{attempts}/#{max_attempts}"
58
+ sleep(10)
59
+ attempts=attempts+1
60
+ rescue Errno::ETIMEDOUT
61
+ logger.debug "Connection timed out. Server may not have booted yet. Sleeping #{attempts}/#{max_attempts}"
62
+ sleep(10)
63
+ attempts=attempts+1
64
+ end
65
+ end
66
+ unless success
67
+ logger.error 'Bootstrapping: failed to find server to connect to'
68
+ raise 'Bootstrapping: failed to find server to connect to'
69
+ end
70
+ end
71
+
72
+ def ssh_command(session)
73
+ raise 'Unimplemented...'
74
+ end
75
+ end
76
+
77
+ class SshCommandTask < AvstCloud::SshTask
78
+ include Logging
79
+
80
+ def initialize(cmds, debug = false, structured_log = false)
81
+ @cmds = cmds
82
+ @debug = debug
83
+ @structured_log = structured_log
84
+ end
85
+
86
+ def ssh_command(session)
87
+ Array(@cmds).each do |cmd|
88
+ next unless cmd
89
+ cmd.strip!
90
+ next if cmd == ""
91
+ logger.debug("Running command on server as root: sudo su -c \"#{cmd}\"")
92
+ start_time = Time.now
93
+
94
+ session.exec!("sudo su -c \"#{cmd}\"") do |ch, stream, data|
95
+ if @debug
96
+ logger.debug "Got this on the #{stream} stream: "
97
+ if @structured_log && logger.methods.include?(:log_structured_code)
98
+ logger.log_structured_code(data)
99
+ else
100
+ logger.debug(data)
101
+ end
102
+ end
103
+ end
104
+ total_time = Time.now - start_time
105
+ logger.debug("Completed in #{total_time} seconds")
106
+ end
107
+ end
108
+ end
109
+
110
+ # In case Requiretty is set in sudoers disable it for bootstrapping and provisioning
111
+ # for user that performs it
112
+ class DisableRequireTty < AvstCloud::SshTask
113
+ include Logging
114
+ def initialize(for_user)
115
+ @for_user = for_user
116
+ end
117
+ def ssh_command(session)
118
+ session.open_channel do |channel|
119
+ channel.request_pty do |ch, success|
120
+ raise 'Error requesting pty' unless success
121
+
122
+ ch.send_channel_request('shell') do |ch, success|
123
+ raise 'Error opening shell' unless success
124
+ end
125
+ end
126
+ channel.on_data do |ch, data|
127
+ if @debug
128
+ STDOUT.print data
129
+ end
130
+ end
131
+ channel.on_extended_data do |ch, type, data|
132
+ STDOUT.print "Error: #{data}\n"
133
+ end
134
+ channel.send_data("sudo su -c 'echo 'Defaults:#{@for_user}\\ \\!requiretty' >> /etc/sudoers'\n")
135
+ channel.send_data("exit\n")
136
+ session.loop
137
+ end
138
+ end
139
+ end
140
+
141
+ class WaitUntilReady < AvstCloud::SshTask
142
+ include Logging
143
+
144
+ def ssh_command(session)
145
+ session.open_channel do |channel|
146
+ channel.request_pty do |ch, success|
147
+ raise 'Error requesting pty' unless success
148
+
149
+ ch.send_channel_request("shell") do |ch, success|
150
+ raise 'Error opening shell' unless success
151
+ end
152
+ end
153
+ channel.on_data do |ch, data|
154
+ if @debug
155
+ STDOUT.print data
156
+ end
157
+ end
158
+ channel.on_extended_data do |ch, type, data|
159
+ STDOUT.print "Error: #{data}\n"
160
+ end
161
+ channel.send_data("echo \"ready\"\n")
162
+ channel.send_data("exit\n")
163
+ session.loop
164
+ end
165
+ end
166
+ end
167
+
168
+ class CapistranoDeploymentTask < AvstCloud::Task
169
+ include Logging
170
+
171
+ def initialize(git, branch, server_tmp_folder = "/tmp/avst_cloud_tmp_#{Time.now.to_i}", reference = nil, custom_provisioning_commands = [], puppet_runner = nil, puppet_runner_prepare = nil, destination_folder = '/var/opt/puppet')
172
+ unless git and (branch or reference)
173
+ logger.debug "You have to provide git repo url #{git} and git branch #{branch} or git tag reference #{reference}".red
174
+ raise "You have to provide git repo url #{git} and git branch #{branch} or git tag reference #{reference}"
175
+ end
176
+
177
+ @git = git
178
+ @branch = branch
179
+ @server_tmp_folder = server_tmp_folder
180
+ @reference = reference
181
+ @custom_provisioning_commands = custom_provisioning_commands || []
182
+ @puppet_runner = puppet_runner
183
+ @puppet_runner_prepare = puppet_runner_prepare
184
+ @destination_folder = destination_folder || '/var/opt/puppet'
185
+ end
186
+
187
+ def execute(server)
188
+ unless server.ip_address
189
+ logger.error 'Can not find host'.red
190
+ raise 'Can not find ip address, access_user or access_password'
191
+ end
192
+
193
+ unless server.access_user
194
+ logger.error 'Access user not found. Please provide username for this server.'.red
195
+ raise 'Access user not found. Please provide username for this server.'
196
+ end
197
+
198
+ unless server.access_password
199
+ logger.error 'Password not found. Please provide password or pem key for this server.'.red
200
+ raise 'Password not found. Please provide root_password in config. for this server.'
201
+ end
202
+
203
+ logger.debug "Using #{server.access_user}@#{server.ip_address} with #{server.access_password}"
204
+
205
+
206
+ # Initiate capistrano deploy script to download the laters code and provision the server
207
+ require 'capistrano/all'
208
+ require 'capistrano/setup'
209
+ require 'capistrano/deploy'
210
+ Dir.glob("#{File.dirname __dir__}/capistrano/tasks/*.rake").each { |r| load r }
211
+ # cap production deploy
212
+ ENV['cap_git_repo_url'] = @git
213
+ ENV['cap_branch_name'] = @branch
214
+ ENV['cap_reference_name'] = @reference
215
+ ENV['cap_ip_address'] = server.ip_address
216
+ ENV['cap_access_password'] = server.access_password
217
+ ENV['cap_access_user'] = server.access_user
218
+ ENV['server_name'] = server.server_name
219
+ ENV['puppet_runner'] = @puppet_runner
220
+ ENV['puppet_runner_prepare'] = @puppet_runner_prepare
221
+ ENV['avst_cloud_tmp_folder'] = @server_tmp_folder
222
+ ENV['custom_provisioning_commands'] = @custom_provisioning_commands.to_json
223
+ ENV['destination_folder'] = @destination_folder
224
+ logger.debug "Using git #{@git} branch #{@branch} to provision #{server.ip_address}"
225
+
226
+ Capistrano::Application.invoke('production')
227
+ Capistrano::Application.invoke('deploy')
228
+ logger.debug "You can connect to server on #{server.ip_address}"
229
+ end
230
+ end
231
+
232
+ class PostProvisionCleanup < AvstCloud::SshCommandTask
233
+
234
+ def initialize(os, debug, tmp_folder = "/tmp/avst_cloud_tmp_#{Time.now.to_i}")
235
+ super(make_commands(os, tmp_folder), debug, false)
236
+ end
237
+
238
+ def make_commands(os, tmp_folder)
239
+ cmds = []
240
+ case os
241
+ when /ubuntu/, /debian/
242
+ cmds << 'apt-get clean'
243
+
244
+ when /centos/, /redhat/
245
+ cmds << 'yum clean all'
246
+ end
247
+ cmds << "rm -rf #{tmp_folder}"
248
+ cmds
249
+ end
250
+ end
251
+
252
+ class ScpTask < AvstCloud::Task
253
+ include Logging
254
+
255
+ def initialize(files)
256
+ @files = files
257
+ end
258
+
259
+ def execute(server)
260
+ unless server.ip_address
261
+ logger.error 'Can not find host'.red
262
+ raise 'Can not find ip address, access_user or access_password'
263
+ end
264
+
265
+ unless server.access_user
266
+ logger.error 'Access user not found. Please provide username for this server.'.red
267
+ raise 'Access user not found. Please provide username for this server.'
268
+ end
269
+
270
+ unless server.access_password
271
+ logger.error 'Password not found. Please provide password or pem key for this server.'.red
272
+ raise 'Password not found. Please provide root_password in config. for this server.'
273
+ end
274
+
275
+ logger.debug "Using #{server.access_user}@#{server.ip_address} with #{server.access_password}"
276
+ Net::SCP.start( server.ip_address, server.access_user, :password => server.access_password, :keys => [server.access_password] ) do |scp|
277
+ @files.each do |local_file, remote_path|
278
+ upload_file(scp, local_file, remote_path)
279
+ end
280
+ end
281
+ end
282
+
283
+ def upload_file(scp, local_path, remote_path)
284
+ logger.debug("Uploading file on server: #{local_path} to #{remote_path}")
285
+ scp.upload!( local_path, remote_path)
286
+ end
287
+ end
288
+ end