hetzner-bootstrap 1.3.0 → 1.4.1
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 +5 -5
- data/.rubocop.yml +7 -1
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +7 -16
- data/Rakefile +2 -0
- data/example.rb +81 -79
- data/hetzner-bootstrap.gemspec +12 -8
- data/lib/hetzner-bootstrap.rb +5 -3
- data/lib/hetzner/bootstrap/target.rb +26 -25
- data/lib/hetzner/bootstrap/template.rb +3 -1
- data/lib/hetzner/bootstrap/version.rb +2 -1
- data/spec/hetzner_bootstrap_spec.rb +5 -1
- data/spec/spec_helper.rb +3 -2
- metadata +58 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c046fd83b8ed81c4c74dfe015a5940f058fa12da1201f81e44255edc9e3e1393
|
4
|
+
data.tar.gz: 55e2a6efaac4d0740f19155460c3f61b4954f6b93f5001b617235583e4305abd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5e34d87321153b348a88e7a1f9eab7144a6cf65338aed28198ba8ced434b6ddc8c9ea16ef7968c24bd9ebfff71f8f6bf1dcb267f0c11d3e9d3a4e3a1793832a
|
7
|
+
data.tar.gz: 445f109cd2029f0b530ae757a5603c6539e42d001d827f34bec57f1bb0ea196d761ba0c91e202bf9e11242f51eec48f6301e4477875dfbe3e2af4db0d28a8753
|
data/.rubocop.yml
CHANGED
@@ -1,15 +1,21 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.6
|
3
|
+
|
1
4
|
Metrics/LineLength:
|
2
5
|
Enabled: false
|
3
6
|
|
4
7
|
Metrics/MethodLength:
|
5
8
|
Enabled: false
|
6
9
|
|
7
|
-
|
10
|
+
Naming/FileName:
|
8
11
|
Enabled: false
|
9
12
|
|
10
13
|
Style/Documentation:
|
11
14
|
Enabled: false
|
12
15
|
|
16
|
+
Layout/IndentHeredoc:
|
17
|
+
EnforcedStyle: squiggly
|
18
|
+
|
13
19
|
Metrics/ClassLength:
|
14
20
|
Enabled: false
|
15
21
|
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -50,6 +50,7 @@ require 'hetzner-bootstrap'
|
|
50
50
|
bs = Hetzner::Bootstrap.new(api: Hetzner::API.new(ENV['ROBOT_USER'], ENV['ROBOT_PASSWORD']))
|
51
51
|
|
52
52
|
template = <<EOT
|
53
|
+
# see https://github.com/hetzneronline/installimage/
|
53
54
|
DRIVE1 /dev/sda
|
54
55
|
DRIVE2 /dev/sdb
|
55
56
|
|
@@ -128,7 +129,7 @@ post_install = <<EOT
|
|
128
129
|
# knife bootstrap <%= ip %> -N <%= hostname %> "role[base],role[kvm_host]"
|
129
130
|
EOT
|
130
131
|
|
131
|
-
bs << {
|
132
|
+
bs << {
|
132
133
|
ip: '1.2.3.4',
|
133
134
|
template: template, # string will be parsed by erubis
|
134
135
|
hostname: 'server100.example.com', # will be used for setting the systems' hostname
|
@@ -136,7 +137,7 @@ bs << {
|
|
136
137
|
post_install: post_install # will be called locally at the end and can be used e.g. to run a chef bootstrap
|
137
138
|
}
|
138
139
|
|
139
|
-
bs << {
|
140
|
+
bs << {
|
140
141
|
ip: '1.2.3.5',
|
141
142
|
template: template, # string will be parsed by erubis
|
142
143
|
hostname: 'server101.example.com', # will be used for setting the systems' hostname
|
@@ -144,7 +145,7 @@ bs << {
|
|
144
145
|
post_install: post_install # will be called locally at the end and can be used e.g. to run a chef bootstrap
|
145
146
|
}
|
146
147
|
|
147
|
-
|
148
|
+
...
|
148
149
|
bs.bootstrap!
|
149
150
|
|
150
151
|
|
@@ -159,23 +160,13 @@ Warnings:
|
|
159
160
|
---------
|
160
161
|
|
161
162
|
* All existing data on the system will be wiped on bootstrap!
|
162
|
-
* This is not an official Hetzner
|
163
|
-
* The gem and the author are not related to Hetzner
|
163
|
+
* This is not an official Hetzner Online GmbH project.
|
164
|
+
* The gem and the author are not related to Hetzner Online GmbH !
|
164
165
|
|
165
166
|
**Use at your very own risk. Satisfaction is NOT guaranteed.**
|
166
167
|
|
167
|
-
Commercial Support available through:
|
168
|
-
-------------------------------------
|
169
|
-
|
170
|
-
[](http://moriz.de/)
|
171
|
-
|
172
|
-
[Moriz GmbH, München](http://moriz.de/)
|
173
|
-
|
174
168
|
|
175
169
|
Copyright
|
176
170
|
---------
|
177
171
|
|
178
|
-
Copyright ©
|
179
|
-
|
180
|
-
[](http://www.linkedin.com/in/rmoriz)
|
181
|
-
[](https://twitter.com/rmoriz)
|
172
|
+
Copyright © 2019 [Roland Moriz](https://roland.io), [Moriz GmbH](https://moriz.de/)
|
data/Rakefile
CHANGED
data/example.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require 'rubygems'
|
3
5
|
require 'hetzner-bootstrap'
|
4
6
|
|
@@ -16,90 +18,90 @@ bs = Hetzner::Bootstrap.new(api: Hetzner::API.new(
|
|
16
18
|
))
|
17
19
|
|
18
20
|
# 2 disks, software raid 1, etc.
|
19
|
-
template =
|
20
|
-
DRIVE1 /dev/sda
|
21
|
-
DRIVE2 /dev/sdb
|
22
|
-
FORMATDRIVE2 0
|
23
|
-
|
24
|
-
## ===============
|
25
|
-
## SOFTWARE RAID:
|
26
|
-
## ===============
|
27
|
-
|
28
|
-
## activate software RAID? < 0 | 1 >
|
29
|
-
SWRAID 1
|
30
|
-
|
31
|
-
## Choose the level for the software RAID < 0 | 1 >
|
32
|
-
SWRAIDLEVEL 1
|
33
|
-
|
34
|
-
## which bootloader should be used? < lilo | grub >
|
35
|
-
BOOTLOADER grub
|
36
|
-
|
37
|
-
HOSTNAME <%= hostname %>
|
38
|
-
|
39
|
-
## PART <mountpoint/lvm> <filesystem/VG> <size in MB>
|
40
|
-
##
|
41
|
-
## * <mountpoint/lvm> mountpoint for this filesystem *OR* keyword 'lvm'
|
42
|
-
## to use this PART as volume group (VG) for LVM
|
43
|
-
## * <filesystem/VG> can be ext2, ext3, reiserfs, xfs, swap *OR* name
|
44
|
-
## of the LVM volume group (VG), if this PART is a VG
|
45
|
-
## * <size> you can use the keyword 'all' to assign all the
|
46
|
-
## remaining space of the drive to the *last* partition.
|
47
|
-
## you can use M/G/T for unit specification in MIB/GIB/TIB
|
48
|
-
##
|
49
|
-
## notes:
|
50
|
-
## - extended partitions are created automatically
|
51
|
-
## - '/boot' cannot be on a xfs filesystem!
|
52
|
-
## - '/boot' cannot be on LVM!
|
53
|
-
## - when using software RAID 0, you need a '/boot' partition
|
54
|
-
|
55
|
-
PART /boot ext2 1G
|
56
|
-
PART lvm host 75G
|
57
|
-
PART lvm guest all
|
58
|
-
|
59
|
-
#LV <VG> <name> <mount> <filesystem> <size>
|
60
|
-
LV host root / ext3 50G
|
61
|
-
LV host swap swap swap 5G
|
62
|
-
|
63
|
-
|
64
|
-
## ========================
|
65
|
-
## OPERATING SYSTEM IMAGE:
|
66
|
-
## ========================
|
67
|
-
|
68
|
-
## full path to the operating system image
|
69
|
-
## supported image sources: local dir, ftp, http, nfs
|
70
|
-
## supported image types: tar, tar.gz, tar.bz, tar.bz2, tgz, tbz
|
71
|
-
## examples:
|
72
|
-
#
|
73
|
-
# local: /path/to/image/filename.tar.gz
|
74
|
-
# ftp: ftp://<user>:<password>@hostname/path/to/image/filename.tar.bz2
|
75
|
-
# http: http://<user>:<password>@hostname/path/to/image/filename.tbz
|
76
|
-
# https: https://<user>:<password>@hostname/path/to/image/filename.tbz
|
77
|
-
# nfs: hostname:/path/to/image/filename.tgz
|
78
|
-
|
79
|
-
# Default images provided by hetzner as of October 2014:
|
80
|
-
# Archlinux-2014-64-minmal.tar.gz
|
81
|
-
# CentOS-65-32-minimal.tar.gz
|
82
|
-
# CentOS-65-64-cpanel.tar.gz
|
83
|
-
# CentOS-65-64-minimal.tar.gz
|
84
|
-
# CentOS-70-64-minimal.tar.gz
|
85
|
-
# Debian-76-wheezy-32-minimal.tar.gz
|
86
|
-
# Debian-76-wheezy-64-LAMP.tar.gz
|
87
|
-
# Debian-76-wheezy-64-minimal.tar.gz
|
88
|
-
# openSUSE-131-64-minimal.tar.gz
|
89
|
-
# Ubuntu-1204-precise-64-minimal.tar.gz
|
90
|
-
# Ubuntu-1404-trusty-64-minimal.tar.gz
|
91
|
-
|
92
|
-
|
93
|
-
IMAGE /root/images/Ubuntu-1204-precise-64-minimal.tar.gz
|
94
|
-
|
95
|
-
|
21
|
+
template = <<~END_OF_TEMPLATE
|
22
|
+
DRIVE1 /dev/sda
|
23
|
+
DRIVE2 /dev/sdb
|
24
|
+
FORMATDRIVE2 0
|
25
|
+
|
26
|
+
## ===============
|
27
|
+
## SOFTWARE RAID:
|
28
|
+
## ===============
|
29
|
+
|
30
|
+
## activate software RAID? < 0 | 1 >
|
31
|
+
SWRAID 1
|
32
|
+
|
33
|
+
## Choose the level for the software RAID < 0 | 1 >
|
34
|
+
SWRAIDLEVEL 1
|
35
|
+
|
36
|
+
## which bootloader should be used? < lilo | grub >
|
37
|
+
BOOTLOADER grub
|
38
|
+
|
39
|
+
HOSTNAME <%= hostname %>
|
40
|
+
|
41
|
+
## PART <mountpoint/lvm> <filesystem/VG> <size in MB>
|
42
|
+
##
|
43
|
+
## * <mountpoint/lvm> mountpoint for this filesystem *OR* keyword 'lvm'
|
44
|
+
## to use this PART as volume group (VG) for LVM
|
45
|
+
## * <filesystem/VG> can be ext2, ext3, reiserfs, xfs, swap *OR* name
|
46
|
+
## of the LVM volume group (VG), if this PART is a VG
|
47
|
+
## * <size> you can use the keyword 'all' to assign all the
|
48
|
+
## remaining space of the drive to the *last* partition.
|
49
|
+
## you can use M/G/T for unit specification in MIB/GIB/TIB
|
50
|
+
##
|
51
|
+
## notes:
|
52
|
+
## - extended partitions are created automatically
|
53
|
+
## - '/boot' cannot be on a xfs filesystem!
|
54
|
+
## - '/boot' cannot be on LVM!
|
55
|
+
## - when using software RAID 0, you need a '/boot' partition
|
56
|
+
|
57
|
+
PART /boot ext2 1G
|
58
|
+
PART lvm host 75G
|
59
|
+
PART lvm guest all
|
60
|
+
|
61
|
+
#LV <VG> <name> <mount> <filesystem> <size>
|
62
|
+
LV host root / ext3 50G
|
63
|
+
LV host swap swap swap 5G
|
64
|
+
|
65
|
+
|
66
|
+
## ========================
|
67
|
+
## OPERATING SYSTEM IMAGE:
|
68
|
+
## ========================
|
69
|
+
|
70
|
+
## full path to the operating system image
|
71
|
+
## supported image sources: local dir, ftp, http, nfs
|
72
|
+
## supported image types: tar, tar.gz, tar.bz, tar.bz2, tgz, tbz
|
73
|
+
## examples:
|
74
|
+
#
|
75
|
+
# local: /path/to/image/filename.tar.gz
|
76
|
+
# ftp: ftp://<user>:<password>@hostname/path/to/image/filename.tar.bz2
|
77
|
+
# http: http://<user>:<password>@hostname/path/to/image/filename.tbz
|
78
|
+
# https: https://<user>:<password>@hostname/path/to/image/filename.tbz
|
79
|
+
# nfs: hostname:/path/to/image/filename.tgz
|
80
|
+
|
81
|
+
# Default images provided by hetzner as of October 2014:
|
82
|
+
# Archlinux-2014-64-minmal.tar.gz
|
83
|
+
# CentOS-65-32-minimal.tar.gz
|
84
|
+
# CentOS-65-64-cpanel.tar.gz
|
85
|
+
# CentOS-65-64-minimal.tar.gz
|
86
|
+
# CentOS-70-64-minimal.tar.gz
|
87
|
+
# Debian-76-wheezy-32-minimal.tar.gz
|
88
|
+
# Debian-76-wheezy-64-LAMP.tar.gz
|
89
|
+
# Debian-76-wheezy-64-minimal.tar.gz
|
90
|
+
# openSUSE-131-64-minimal.tar.gz
|
91
|
+
# Ubuntu-1204-precise-64-minimal.tar.gz
|
92
|
+
# Ubuntu-1404-trusty-64-minimal.tar.gz
|
93
|
+
|
94
|
+
|
95
|
+
IMAGE /root/images/Ubuntu-1204-precise-64-minimal.tar.gz
|
96
|
+
|
97
|
+
END_OF_TEMPLATE
|
96
98
|
|
97
99
|
# the post_install hook is a great place to setup further
|
98
100
|
# software/system provisioning
|
99
101
|
#
|
100
|
-
post_install = <<
|
102
|
+
post_install = <<END_OF_POST_INSTALL
|
101
103
|
# knife bootstrap <%= ip %> -N <%= hostname %> "role[base],role[kvm_host]"
|
102
|
-
|
104
|
+
END_OF_POST_INSTALL
|
103
105
|
|
104
106
|
# duplicate entry for each system
|
105
107
|
bs << { ip: '1.2.3.4',
|
data/hetzner-bootstrap.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
3
4
|
require 'hetzner/bootstrap/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
@@ -8,17 +9,20 @@ Gem::Specification.new do |s|
|
|
8
9
|
s.platform = Gem::Platform::RUBY
|
9
10
|
s.authors = ['Roland Moriz']
|
10
11
|
s.email = ['roland@moriz.de']
|
11
|
-
s.homepage = '
|
12
|
+
s.homepage = 'https://github.com/rmoriz/hetzner-bootstrap'
|
12
13
|
s.summary = 'Easy bootstrapping of hetzner.de rootservers using hetzner-api'
|
13
14
|
s.description = 'Easy bootstrapping of hetzner.de rootservers using hetzner-api'
|
14
15
|
|
15
|
-
s.add_dependency '
|
16
|
-
s.add_dependency '
|
17
|
-
s.add_dependency '
|
16
|
+
s.add_dependency 'bcrypt_pbkdf', '>= 1.0', '< 2.0'
|
17
|
+
s.add_dependency 'ed25519', '>= 1.2', '< 2.0'
|
18
|
+
s.add_dependency 'hetzner-api', '>= 1.1.0'
|
19
|
+
s.add_dependency 'net-ssh', '>= 5.1.0'
|
20
|
+
|
21
|
+
s.add_dependency 'erubis', '>= 2.7.0'
|
18
22
|
|
19
|
-
s.add_development_dependency 'rspec', '~> 3.4.0'
|
20
23
|
s.add_development_dependency 'rake'
|
21
|
-
s.add_development_dependency '
|
24
|
+
s.add_development_dependency 'rspec', '~> 3.4.0'
|
25
|
+
s.add_development_dependency 'rubocop', '~> 0.63.1'
|
22
26
|
|
23
27
|
s.files = `git ls-files`.split("\n")
|
24
28
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/hetzner-bootstrap.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'benchmark'
|
2
4
|
require 'logger'
|
3
5
|
|
@@ -15,7 +17,7 @@ module Hetzner
|
|
15
17
|
|
16
18
|
def initialize(options = {})
|
17
19
|
@targets = []
|
18
|
-
@actions = %w
|
20
|
+
@actions = %w[enable_rescue_mode
|
19
21
|
reset
|
20
22
|
wait_for_ssh_down
|
21
23
|
wait_for_ssh_up
|
@@ -27,7 +29,7 @@ module Hetzner
|
|
27
29
|
copy_ssh_keys
|
28
30
|
update_local_known_hosts
|
29
31
|
post_install
|
30
|
-
post_install_remote
|
32
|
+
post_install_remote]
|
31
33
|
@api = options[:api]
|
32
34
|
@logger = options[:logger] || Logger.new(STDOUT)
|
33
35
|
end
|
@@ -65,7 +67,7 @@ module Hetzner
|
|
65
67
|
end
|
66
68
|
target.logger.info "#{loghack}[#{action}] FINISHED in #{format '%.5f', d} seconds"
|
67
69
|
end
|
68
|
-
rescue => e
|
70
|
+
rescue StandardError => e
|
69
71
|
puts "something bad happened unexpectedly: #{e.class} => #{e.message}"
|
70
72
|
end
|
71
73
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'erubis'
|
2
4
|
require 'net/ssh'
|
3
5
|
require 'socket'
|
@@ -14,8 +16,8 @@ module Hetzner
|
|
14
16
|
attr_accessor :rescue_os_bit
|
15
17
|
attr_accessor :actions
|
16
18
|
attr_accessor :hostname
|
17
|
-
|
18
|
-
|
19
|
+
attr_writer :post_install
|
20
|
+
attr_writer :post_install_remote
|
19
21
|
attr_accessor :public_keys
|
20
22
|
attr_accessor :bootstrap_cmd
|
21
23
|
attr_accessor :logger
|
@@ -30,7 +32,7 @@ module Hetzner
|
|
30
32
|
|
31
33
|
@template = Template.new options.delete(:template)
|
32
34
|
|
33
|
-
|
35
|
+
raise NoTemplateProvidedError 'No imageinstall template provided.' unless @template
|
34
36
|
|
35
37
|
options.each_pair do |k, v|
|
36
38
|
send("#{k}=", v)
|
@@ -46,7 +48,7 @@ module Hetzner
|
|
46
48
|
logger.info "IP: #{ip} => password: #{@password}"
|
47
49
|
elsif @retries > 3
|
48
50
|
logger.error 'rescue system could not be activated'
|
49
|
-
|
51
|
+
raise CantActivateRescueSystemError, result
|
50
52
|
else
|
51
53
|
@retries += 1
|
52
54
|
|
@@ -65,7 +67,7 @@ module Hetzner
|
|
65
67
|
reset_retries
|
66
68
|
elsif @retries > 3
|
67
69
|
logger.error 'resetting through webservice failed.'
|
68
|
-
|
70
|
+
raise CantResetSystemError, result
|
69
71
|
else
|
70
72
|
@retries += 1
|
71
73
|
logger.warn "problem while trying to reset/reboot system (retries: #{@retries})"
|
@@ -85,7 +87,8 @@ module Hetzner
|
|
85
87
|
loop do
|
86
88
|
sleep 2
|
87
89
|
Timeout.timeout(4) do
|
88
|
-
|
90
|
+
raise Errno::ECONNREFUSED unless port_open? @ip, 22
|
91
|
+
|
89
92
|
logger.debug 'SSH UP'
|
90
93
|
end
|
91
94
|
end
|
@@ -96,7 +99,7 @@ module Hetzner
|
|
96
99
|
def wait_for_ssh_up
|
97
100
|
loop do
|
98
101
|
Timeout.timeout(4) do
|
99
|
-
|
102
|
+
raise Errno::ECONNREFUSED unless port_open? @ip, 22
|
100
103
|
|
101
104
|
logger.debug 'SSH UP'
|
102
105
|
return true
|
@@ -117,42 +120,38 @@ module Hetzner
|
|
117
120
|
output = ssh.exec!(@bootstrap_cmd)
|
118
121
|
logger.info output.gsub(`clear`, '')
|
119
122
|
end
|
120
|
-
|
121
|
-
rescue Net::SSH::Disconnect
|
122
|
-
puts 'SSH connection was closed.'
|
123
123
|
end
|
124
124
|
|
125
125
|
def reboot
|
126
126
|
remote do |ssh|
|
127
127
|
ssh.exec!('reboot')
|
128
128
|
end
|
129
|
-
rescue Net::SSH::Disconnect
|
130
|
-
|
129
|
+
rescue IOError, Net::SSH::Disconnect
|
130
|
+
logger.debug 'SSH connection was closed as anticipated.'
|
131
131
|
end
|
132
132
|
|
133
133
|
def verify_installation
|
134
134
|
remote do |ssh|
|
135
135
|
working_hostname = ssh.exec!('cat /etc/hostname')
|
136
|
-
|
137
|
-
|
138
|
-
end
|
136
|
+
working_hostname.chomp!
|
137
|
+
logger.debug "hostnames do not match: assumed #{@hostname} but received #{working_hostname}" unless @hostname == working_hostname.chomp
|
139
138
|
end
|
140
139
|
end
|
141
140
|
|
142
141
|
def copy_ssh_keys
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
142
|
+
return unless @public_keys
|
143
|
+
|
144
|
+
remote do |ssh|
|
145
|
+
ssh.exec!('mkdir /root/.ssh')
|
146
|
+
Array(@public_keys).each do |key|
|
147
|
+
pub = File.read(File.expand_path(key))
|
148
|
+
ssh.exec!("echo \"#{pub}\" >> /root/.ssh/authorized_keys")
|
150
149
|
end
|
151
150
|
end
|
152
151
|
end
|
153
152
|
|
154
153
|
def update_local_known_hosts
|
155
|
-
remote(verify_host_key:
|
154
|
+
remote(verify_host_key: :accept_new_or_local_tunnel) do |ssh|
|
156
155
|
# dummy
|
157
156
|
end
|
158
157
|
rescue Net::SSH::HostKeyMismatch => e
|
@@ -181,6 +180,8 @@ module Hetzner
|
|
181
180
|
ssh.exec!(cmd)
|
182
181
|
end
|
183
182
|
end
|
183
|
+
rescue IOError, Net::SSH::Disconnect
|
184
|
+
logger.debug 'SSH connection was closed.'
|
184
185
|
end
|
185
186
|
|
186
187
|
def render_template
|
@@ -215,7 +216,7 @@ module Hetzner
|
|
215
216
|
end
|
216
217
|
|
217
218
|
def remote(options = {})
|
218
|
-
default = { verify_host_key:
|
219
|
+
default = { verify_host_key: :never, password: @password }
|
219
220
|
default.merge! options
|
220
221
|
|
221
222
|
Net::SSH.start(@ip, @login, default) do |ssh|
|
@@ -238,7 +239,7 @@ module Hetzner
|
|
238
239
|
|
239
240
|
def default_log_formatter
|
240
241
|
proc do |_severity, datetime, _progname, msg|
|
241
|
-
caller
|
242
|
+
caller(5..5).first =~ /`(.*?)'/
|
242
243
|
"[#{datetime.strftime '%H:%M:%S'}][#{format '%-15s', ip}]" \
|
243
244
|
"[#{Regexp.last_match(1)}] #{msg}\n"
|
244
245
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Hetzner
|
2
4
|
class Bootstrap
|
3
5
|
class Template
|
@@ -13,7 +15,7 @@ module Hetzner
|
|
13
15
|
# also run: $ installimage -h
|
14
16
|
#
|
15
17
|
if param.is_a? Hetzner::Bootstrap::Template
|
16
|
-
|
18
|
+
param
|
17
19
|
elsif param.is_a? String
|
18
20
|
@raw_template = param
|
19
21
|
end
|
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'hetzner-api'
|
2
4
|
require 'hetzner-bootstrap'
|
3
5
|
|
6
|
+
# rubocop:disable Metrics/BlockLength
|
4
7
|
describe 'Bootstrap' do
|
5
8
|
let(:bs) do
|
6
9
|
Hetzner::Bootstrap.new(api: Hetzner::API.new(API_USERNAME, API_PASSWORD))
|
@@ -33,10 +36,11 @@ describe 'Bootstrap' do
|
|
33
36
|
end
|
34
37
|
|
35
38
|
def improper_target_without_template
|
36
|
-
proper_target.
|
39
|
+
proper_target.reject { |k, _v| k == :template }
|
37
40
|
end
|
38
41
|
|
39
42
|
def default_template
|
40
43
|
'string'
|
41
44
|
end
|
42
45
|
end
|
46
|
+
# rubocop:enable Metrics/BlockLength
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
3
4
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
4
5
|
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
@@ -94,5 +95,5 @@ RSpec.configure do |config|
|
|
94
95
|
# Kernel.srand config.seed
|
95
96
|
end
|
96
97
|
|
97
|
-
API_USERNAME = 'api-login'
|
98
|
-
API_PASSWORD = 'password'
|
98
|
+
API_USERNAME = 'api-login'
|
99
|
+
API_PASSWORD = 'password'
|
metadata
CHANGED
@@ -1,15 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hetzner-bootstrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roland Moriz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bcrypt_pbkdf
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: ed25519
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.2'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '2.0'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.2'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '2.0'
|
13
53
|
- !ruby/object:Gem::Dependency
|
14
54
|
name: hetzner-api
|
15
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -30,14 +70,14 @@ dependencies:
|
|
30
70
|
requirements:
|
31
71
|
- - ">="
|
32
72
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
73
|
+
version: 5.1.0
|
34
74
|
type: :runtime
|
35
75
|
prerelease: false
|
36
76
|
version_requirements: !ruby/object:Gem::Requirement
|
37
77
|
requirements:
|
38
78
|
- - ">="
|
39
79
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
80
|
+
version: 5.1.0
|
41
81
|
- !ruby/object:Gem::Dependency
|
42
82
|
name: erubis
|
43
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,47 +93,47 @@ dependencies:
|
|
53
93
|
- !ruby/object:Gem::Version
|
54
94
|
version: 2.7.0
|
55
95
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
96
|
+
name: rake
|
57
97
|
requirement: !ruby/object:Gem::Requirement
|
58
98
|
requirements:
|
59
|
-
- - "
|
99
|
+
- - ">="
|
60
100
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
101
|
+
version: '0'
|
62
102
|
type: :development
|
63
103
|
prerelease: false
|
64
104
|
version_requirements: !ruby/object:Gem::Requirement
|
65
105
|
requirements:
|
66
|
-
- - "
|
106
|
+
- - ">="
|
67
107
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
108
|
+
version: '0'
|
69
109
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
110
|
+
name: rspec
|
71
111
|
requirement: !ruby/object:Gem::Requirement
|
72
112
|
requirements:
|
73
|
-
- - "
|
113
|
+
- - "~>"
|
74
114
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
115
|
+
version: 3.4.0
|
76
116
|
type: :development
|
77
117
|
prerelease: false
|
78
118
|
version_requirements: !ruby/object:Gem::Requirement
|
79
119
|
requirements:
|
80
|
-
- - "
|
120
|
+
- - "~>"
|
81
121
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
122
|
+
version: 3.4.0
|
83
123
|
- !ruby/object:Gem::Dependency
|
84
124
|
name: rubocop
|
85
125
|
requirement: !ruby/object:Gem::Requirement
|
86
126
|
requirements:
|
87
127
|
- - "~>"
|
88
128
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
129
|
+
version: 0.63.1
|
90
130
|
type: :development
|
91
131
|
prerelease: false
|
92
132
|
version_requirements: !ruby/object:Gem::Requirement
|
93
133
|
requirements:
|
94
134
|
- - "~>"
|
95
135
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
136
|
+
version: 0.63.1
|
97
137
|
description: Easy bootstrapping of hetzner.de rootservers using hetzner-api
|
98
138
|
email:
|
99
139
|
- roland@moriz.de
|
@@ -116,7 +156,7 @@ files:
|
|
116
156
|
- lib/hetzner/bootstrap/version.rb
|
117
157
|
- spec/hetzner_bootstrap_spec.rb
|
118
158
|
- spec/spec_helper.rb
|
119
|
-
homepage:
|
159
|
+
homepage: https://github.com/rmoriz/hetzner-bootstrap
|
120
160
|
licenses: []
|
121
161
|
metadata: {}
|
122
162
|
post_install_message:
|
@@ -135,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
175
|
version: '0'
|
136
176
|
requirements: []
|
137
177
|
rubyforge_project:
|
138
|
-
rubygems_version: 2.6
|
178
|
+
rubygems_version: 2.7.6
|
139
179
|
signing_key:
|
140
180
|
specification_version: 4
|
141
181
|
summary: Easy bootstrapping of hetzner.de rootservers using hetzner-api
|