hetzner-bootstrap 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ hetzner-bootstrap
2
+ =================
3
+
4
+ hetzner-bootstrap allows you to bootstrap a provisioned EQ Server from hetzner.de
5
+
6
+ What it does:
7
+ -------------
8
+
9
+ When you purchase a lot of servers at hetzner you're usually ending in reinstalling
10
+ each system manually prior to the first usage because you may have different opinions
11
+ about partitioning or RAID levels. This rubygem helps to fully automate the provisioning
12
+ of a rootserver.
13
+
14
+ Warning: All existing data on the system will be lost!
15
+
16
+ Requirements:
17
+ -------------
18
+
19
+ - get a webservice login from your customer panel (https://robot.your-server.de/)
20
+ - the ip address of the shipped, running system(s)
21
+
22
+ Implemented steps:
23
+ ------------------
24
+
25
+ 1. Enable Rescue Mode (using Hetzner's webservice)
26
+ 2. Resetting the System to boot into rescue mode (using Hetzner's webservice)
27
+ 3. Log into the rescue system, write your installimage template, execute installation
28
+ 4. Reboot
29
+ 5. verify installation (very basic check but can be overwritten)
30
+ 6. copy your local ssh public-key into root's .authorized_keys
31
+ 7. adds the generated server key into your .know_hosts file
32
+ 8. execute post_install hooks (optional)
33
+
34
+
35
+ Example:
36
+ --------
37
+ **see example.rb file for usage!**
38
+
39
+ Warning: All existing data on the system will be lost!
40
+
41
+ Installation:
42
+ -------------
43
+
44
+ **gem install hetzner-bootstrap**
45
+
46
+ Warnings:
47
+ ---------
48
+
49
+ * All existing data on the system will be wiped on bootstrap!
50
+ * This is not an official Hetzner AG project.
51
+ * The gem and the author are not related to Hetzner AG!
52
+
53
+ **Use at your very own risk. Satisfaction is NOT guaranteed.**
54
+
55
+ Commercial Support available through:
56
+ -------------------------------------
57
+
58
+ [![Moriz GmbH](http://moriz.de/images/logo.png)](http://moriz.de/)
59
+
60
+ [Moriz GmbH, München](http://moriz.de/)
61
+
62
+
63
+ Copyright
64
+ ---------
65
+
66
+ Copyright (c) 2011 Moriz GmbH, Roland Moriz. See LICENSE file for details.
@@ -25,8 +25,8 @@ module Hetzner
25
25
  wait_for_ssh_up
26
26
  verify_installation
27
27
  copy_ssh_keys
28
+ update_local_known_hosts
28
29
  post_install)
29
- #@actions = %w(wait_for_ssh_down)
30
30
  @api = options[:api]
31
31
  @logger = options[:logger] || Logger.new(STDOUT)
32
32
  end
@@ -69,4 +69,5 @@ module Hetzner
69
69
  puts "something bad happened unexpectedly: #{e.class} => #{e.message}"
70
70
  end
71
71
  end
72
- end
72
+ end
73
+
@@ -31,7 +31,7 @@ module Hetzner
31
31
  else
32
32
  raise NoTemplateProvidedError.new 'No imageinstall template provided.'
33
33
  end
34
-
34
+
35
35
  options.each_pair do |k,v|
36
36
  self.send("#{k}=", v)
37
37
  end
@@ -83,21 +83,17 @@ module Hetzner
83
83
 
84
84
  def wait_for_ssh_down(options = {})
85
85
  loop do
86
- Timeout::timeout(3) do
86
+ sleep 2
87
+ Timeout::timeout(4) do
87
88
  if port_open? @ip, 22
88
89
  logger.debug "SSH UP"
89
- sleep 10
90
90
  else
91
91
  raise Errno::ECONNREFUSED
92
92
  end
93
93
  end
94
- sleep 2
95
94
  end
96
- rescue Timeout::Error
97
- sleep 2
98
- retry
99
- rescue Errno::ECONNREFUSED
100
- logger.debug "SHH DOWN"
95
+ rescue Timeout::Error, Errno::ECONNREFUSED
96
+ logger.debug "SSH DOWN"
101
97
  end
102
98
 
103
99
  def wait_for_ssh_up(options = {})
@@ -120,41 +116,32 @@ module Hetzner
120
116
  def installimage(options = {})
121
117
  template = render_template
122
118
 
123
- Net::SSH.start(@ip, @login, :password => @password) do |ssh|
124
- ssh.exec!("echo \"#{template}\" > /tmp/template")
119
+ remote do |ssh|
120
+ ssh.exec! "echo \"#{template}\" > /tmp/template"
125
121
  logger.info "remote executing: #{@bootstrap_cmd}"
126
122
  output = ssh.exec!(@bootstrap_cmd)
127
123
  logger.info output
128
124
  end
129
- rescue Net::SSH::HostKeyMismatch => e
130
- e.remember_host!
131
- retry
132
125
  end
133
126
 
134
127
  def reboot(options = {})
135
- Net::SSH.start(@ip, @login, :password => @password) do |ssh|
128
+ remote do |ssh|
136
129
  ssh.exec!("reboot")
137
130
  end
138
- rescue Net::SSH::HostKeyMismatch => e
139
- e.remember_host!
140
- retry
141
131
  end
142
132
 
143
133
  def verify_installation(options = {})
144
- Net::SSH.start(@ip, @login, :password => @password) do |ssh|
134
+ remote do |ssh|
145
135
  working_hostname = ssh.exec!("cat /etc/hostname")
146
136
  unless @hostname == working_hostname.chomp
147
137
  raise InstallationError, "hostnames do not match: assumed #{@hostname} but received #{working_hostname}"
148
138
  end
149
139
  end
150
- rescue Net::SSH::HostKeyMismatch => e
151
- e.remember_host!
152
- retry
153
140
  end
154
141
 
155
142
  def copy_ssh_keys(options = {})
156
143
  if @public_keys
157
- Net::SSH.start(@ip, @login, :password => @password) do |ssh|
144
+ remote do |ssh|
158
145
  ssh.exec!("mkdir /root/.ssh")
159
146
  @public_keys.to_a.each do |key|
160
147
  pub = File.read(File.expand_path(key))
@@ -162,18 +149,31 @@ module Hetzner
162
149
  end
163
150
  end
164
151
  end
152
+ end
153
+
154
+ def update_local_known_hosts(options = {})
155
+ remote(:paranoid => true) do |ssh|
156
+ # dummy
157
+ end
165
158
  rescue Net::SSH::HostKeyMismatch => e
166
159
  e.remember_host!
167
- retry
160
+ logger.info "remote host key added to local ~/.ssh/known_hosts file."
168
161
  end
169
162
 
170
163
  def post_install(options = {})
171
164
  return unless @post_install
165
+
172
166
  post_install = render_post_install
173
167
  logger.info "executing post_install:\n #{post_install}"
174
- logger.info `#{post_install}`
168
+
169
+ output = local do
170
+ `#{post_install}`
171
+ end
172
+
173
+ logger.info output
175
174
  end
176
175
 
176
+
177
177
  def render_template
178
178
  eruby = Erubis::Eruby.new @template.to_s
179
179
 
@@ -204,6 +204,20 @@ module Hetzner
204
204
  @logger = logger_obj
205
205
  @logger.formatter = default_log_formatter
206
206
  end
207
+
208
+ def remote(options = {}, &block)
209
+
210
+ default = { :paranoid => false, :password => @password }
211
+ default.merge! options
212
+
213
+ Net::SSH.start(@ip, @login, default) do |ssh|
214
+ block.call ssh
215
+ end
216
+ end
217
+
218
+ def local(&block)
219
+ block.call
220
+ end
207
221
 
208
222
  def reset_retries
209
223
  @retries = 0
@@ -1,5 +1,5 @@
1
1
  module Hetzner
2
2
  class Bootstrap
3
- VERSION = '0.0.2'
3
+ VERSION = '0.0.3'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hetzner-bootstrap
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Roland Moriz
@@ -89,7 +89,7 @@ files:
89
89
  - .gitignore
90
90
  - Gemfile
91
91
  - LICENSE
92
- - README.rdoc
92
+ - README.md
93
93
  - Rakefile
94
94
  - example.rb
95
95
  - hetzner-bootstrap.gemspec
@@ -1,32 +0,0 @@
1
- = hetzner-bootstrap
2
-
3
- hetzner-bootstrap allows you to bootstrap a provisioned EQ Server from hetzner.de
4
-
5
- Requirements
6
-
7
- - get a webservice login from your customer panel (https://robot.your-server.de/)
8
- - the ip address of the shipped system(s)
9
-
10
- == Installation
11
-
12
- <tt> gem install hetzner-bootstrap</tt>
13
-
14
- == Example
15
-
16
- <b>see example.rb for usage!</b>
17
-
18
- == WARNING!
19
-
20
- This is not an official Hetzner AG project.
21
-
22
- The gem and the author are not related to Hetzner AG!
23
-
24
- <b>Use at your very own risk! Satisfaction NOT guaranteed!</b>
25
-
26
- == Copyright
27
-
28
- Copyright (c) 2011 Moriz GmbH, Roland Moriz. See LICENSE for details.
29
-
30
- {Ruby on Rails Entwicklung}[http://moriz.de/] -> Moriz GmbH
31
-
32
- {Ruby on Rails Hosting}[http://rails.io/] -> Rails.io