hetzner-boot-freebsd 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2583c2141ddbab2a3ad43db9ce74ced9a2dfd909
4
+ data.tar.gz: 80329d78b46220309c4692c03cc42abd79ed7951
5
+ SHA512:
6
+ metadata.gz: ef722a1e4879c0d3e42ae4012553b9c04c102f05dc5d165a2e56430f822f1a3e5ad247cc1efbfcf8318c6d95d7085de15d1a7cb1c116bd2b0066f237ebbfc7a8
7
+ data.tar.gz: 5bf5340d6a04b73aeb3bf606a877b0b7890f2aff6eec3df908a6a01dea3e1b052ddc8cd25591f1fd46918144835509faf0e337dd14019b30d51e19f9f2923014
@@ -0,0 +1,10 @@
1
+ .idea/*
2
+ bin/*
3
+ *.gem
4
+ .bundle
5
+ Gemfile.lock
6
+ pkg/*
7
+ .rbenv-vars
8
+ .env
9
+ coverage/*
10
+
@@ -0,0 +1,2 @@
1
+ hetzner-boot-freebsd
2
+
@@ -0,0 +1 @@
1
+ ruby-2.2.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hetzner-boot-freebsd.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2015 Asconix Systems AS, Christoph Pilka, http://asconix.com
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
+
11
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,107 @@
1
+ # hetzner-boot-freebsd
2
+
3
+ This gem provides a convenient way to boot a Hetzner root server into FreeBSD rescue environment which is based on [mfsBSD](http://mfsbsd.vx.sk). The mfsBSD project consists of multiple scripts that create a bootable ISO image that create a minimal FreeBSD installation.
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/hetzner-boot-freebsd.png)](http://badge.fury.io/rb/hetzner-boot-freebsd)
6
+
7
+ ## What `hetzner-boot-freebsd` does
8
+
9
+ We are running a considerable number of [FreeBSD](http://www.freebsd.org) servers in production as well as for development. We usually run FreeBSD jail hosts on bare metal servers hosted at Hetzner and encapsulate all services into jails to get a separation of services and to increase the security of the entire setup. We use BSDploy, Ansible and Fabric to provision the jail hosts as well as the FreeBSD jails themselves.
10
+
11
+ An essential step to get the servers provisioned is to have a well-defined starting point which in our case is always a mfsBSD running on the server to be provisioned. Hetzner provides a FreeBSD rescue system that is based on mfsBSD which we use as a starting point to provision the server. This Ruby Gem offers a very convenient way to reboot a Hetzner root server into this rescue environment.
12
+
13
+ This Ruby Gem is basically a stripped down wrapper for the `hetzner-api` Gem with the focus on bringing up any Hetzner server into the FreeBSD rescue system.
14
+
15
+ ## Implemented steps:
16
+
17
+ 1. Enable FreeBSD rescue mode (using Hetzner's webservice)
18
+ 2. Resetting the System to boot into rescue mode (using Hetzner's webservice)
19
+ 3. Log into the rescue system and launch the installation
20
+
21
+ ## Requirements
22
+
23
+ First of all retrieve your API login credentials from the Hetzner admin interface at [https://robot.your-server.de](https://robot.your-server.de). Additionally you need the IP address of the system that you want to provision.
24
+
25
+ ## Installation
26
+
27
+ $~ gem install hetzner-boot-freebsd
28
+
29
+ The `hetzner-freebsd-boot` Ruby Gem requires the credentials for Hetzner's HTTP API to manage the server. These credentials must be available via the environment variables `HETZNER_ROBOT_USERNAME` and `HETZNER_USERNAME_PASSWORD`. You cen set the either in `~/.bash_profile`:
30
+
31
+ export HETZNER_ROBOT_USERNAME="MyHetznerUsername"
32
+ export HETZNER_ROBOT_PASSWORD="MyVerySecretHetznerPW"
33
+
34
+ or create a `.env` file in your Ruby project directory and define them there:
35
+
36
+ HETZNER_ROBOT_USERNAME="MyHetznerUsername"
37
+ HETZNER_ROBOT_PASSWORD="MyVerySecretHetznerPW"
38
+
39
+ ## Example
40
+
41
+ See `example.rb` file for usage. The example requires valid credentials for the Hetzner HTTP API (see the both environment variables `HETZNER_ROBOT_USERNAME` and `HETZNER_ROBOT_PASSWORD` above) as well as a concrete target host to reboot (environment variables `HETZNER_ROBOT_IP_ADDRESS` and `HETZNER_ROBOT_HOSTNAME`). Export them either via your `~/.bash_profile`:
42
+
43
+ export HETZNER_ROBOT_IP_ADDRESS="1.2.3.4"
44
+ export HETZNER_ROBOT_HOSTNAME="freebsd.example com"
45
+
46
+ ... or append them to the `.env` file within your project that will be read by `dotenv`:
47
+
48
+ HETZNER_ROBOT_IP_ADDRESS="1.2.3.4"
49
+ HETZNER_ROBOT_HOSTNAME="freebsd.example com"
50
+
51
+ Afterwards open a new shell and navigate into your project directory. All 4 environment variables should be now exposed for the example code.
52
+
53
+ ```ruby
54
+
55
+ #!/usr/bin/env ruby
56
+ require "rubygems"
57
+ require "hetzner-boot-freebsd"
58
+
59
+ # Retrieve your API login credentials from the Hetzner admin interface
60
+ # at https://robot.your-server.de and assign the appropriate environment
61
+ # variables ENV['ROBOT_USER'] and ENV['ROBOT_PASSWORD']
62
+
63
+ bs = Hetzner::Boot::FreeBSD.new(:api => Hetzner::API.new(ENV['ROBOT_USER'], ENV['ROBOT_PASSWORD']))
64
+
65
+ # The post_install hook is the right place to launch further tasks (e.g.
66
+ # software installation, system provisioning etc.)
67
+ post_install = <<EOT
68
+ # TODO
69
+ EOT
70
+
71
+ bs << {:ip => "1.2.3.4",
72
+ :hostname => 'artemis.asconix.com',
73
+ :public_keys => "~/.ssh/id_rsa.pub",
74
+ :post_install => post_install
75
+ }
76
+
77
+ bs.bootstrap!
78
+
79
+ ```
80
+
81
+ ## Warnings:
82
+
83
+ * All existing data on the system will be wiped on bootstrap!
84
+ * This is not an official Hetzner AG project.
85
+ * The gem and the author are not related to Hetzner AG!
86
+
87
+ **Use at your very own risk. Satisfaction is NOT guaranteed.**
88
+
89
+ ## Thank you greeting
90
+
91
+ This Ruby gem is inspired by the [hetzner-bootstrap](https://github.com/rmoriz/hetzner-bootstrap) gem and requires the underlying wrapper for the Hetzner server management API [hetzner-api](https://github.com/rmoriz/hetzner-api). Thus I want to thank [Roland Moriz](https://roland.io/developer) a lot for his great work!
92
+
93
+ ## Cheat sheet
94
+
95
+ Hetzner provides a very powerfull HTTP API. Here are some simple use cases for this API:
96
+
97
+ *Put a server into rescue mode (here FreeBSD 64-bit)*:
98
+
99
+ $~ curl -u $ROBOT_USER:$ROBOT_PASSWORD https://robot-ws.your-server.de/boot/136.243.0.21/rescue -d 'os=freebsd&arch=64'
100
+
101
+ *Restart the server by hardware reset*:
102
+
103
+ $~ curl -u $ROBOT_USER:$ROBOT_PASSWORD https://robot-ws.your-server.de/reset/136.243.0.21 -d 'type=hw'
104
+
105
+ ## Copyright
106
+
107
+ Copyright (c) 2015 Asconix Systems AS, Christoph Pilka, [http://asconix.com](http://asconix.com)
@@ -0,0 +1,11 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
+
4
+ # Default directory to look within is `/specs`
5
+ # Run with `rake spec`
6
+ RSpec::Core::RakeTask.new(:spec) do |task|
7
+ task.rspec_opts = ['--color', '--format', 'documentation']
8
+ end
9
+
10
+ desc "Run RSpec tests"
11
+ task :default => :spec
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'hetzner-boot-freebsd'
4
+
5
+ # Retrieve your API login credentials from the Hetzner admin interface
6
+ # at https://robot.your-server.de and assign the appropriate environment
7
+ # variables:
8
+ #
9
+ # $~ export HETZNER_ROBOT_USERNAME="MyHetznerUsername"
10
+ # $~ export HETZNER_ROBOT_PASSWORD="MyVerySecretPassword"
11
+ # $~ export HETZNER_ROBOT_IP_ADDRESS="1.2.3.4"
12
+ # $~ export HETZNER_ROBOT_HOSTNAME="freebsd.example.com"
13
+ #
14
+ # Next launch the bootstrap script:
15
+ #
16
+ # $~ ./example.rb
17
+
18
+ api = Hetzner::API.new ENV['HETZNER_ROBOT_USERNAME'], ENV['HETZNER_ROBOT_PASSWORD']
19
+ rescue_env = Hetzner::Boot::FreeBSD.new :api => @api
20
+
21
+ rescue_env << {
22
+ :ip => ENV['HETZNER_ROBOT_IP_ADDRESS'],
23
+ :hostname => ENV['HETZNER_ROBOT_HOSTNAME'],
24
+ :public_keys => 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxpbPqgja8qK0pRBu423nuj7ZqJY/VPyABvBtcHQBpnaz20hSo89K+yEJmdg4upKk54906u7OT5tGaFpTYQKUxGgdKO1my8y2tXHDdTGw1A3BZotgIwDDvNTrIYW8JlGOBTVQuHGm6EYf8tEVut+dhueSe0VsK3keTQQwwatSf4uBgYxRMorsVWFVwk+YH2RKC25pbh0teoagL1TVts4OqGTcRJtrO9PHkuHFNCqA5IQVf+BRzwyCNWGaLuX3W/+DOOx3u76UhKBWrWXicVksFUD7tnFJrZohLu6PtKBoSSlVYVO/YgXQEJtsvG1EmEaoMnM2TvdzIWcopdd2jIo8Cw== c.pilka@asconix.com'
25
+ }
26
+
27
+ rescue_env.bootstrap!
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "hetzner/boot/freebsd/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hetzner-boot-freebsd"
8
+ spec.version = Hetzner::Boot::FreeBSD::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ["Christoph Pilka"]
11
+ spec.email = ["c.pilka@asconix.com"]
12
+ spec.summary = %q{Reboot a Hetzner server into FreeBSD rescue environment}
13
+ spec.description = %q{Allows to reboot a physical server hosted at Hetzner into a minimal FreeBSD recscue environment taht is based on mfsBSD.}
14
+ spec.homepage = "http://www.asconix.com"
15
+ spec.license = "BSD-3"
16
+
17
+ spec.add_dependency 'hetzner-api', '~> 1.1.0'
18
+ spec.add_dependency 'net-ssh', '~> 2.9.2'
19
+ spec.add_dependency 'erubis', '~> 2.7.0'
20
+ spec.add_dependency 'colorize', '~> 0.7.5'
21
+ spec.add_dependency 'highline', '~> 1.7.1'
22
+ spec.add_dependency 'dotenv', '~> 2.0.0'
23
+
24
+ spec.files = `git ls-files -z`.split("\x0")
25
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
26
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_development_dependency "bundler", "~> 1.5"
30
+ spec.add_development_dependency "rake"
31
+ spec.add_development_dependency "rspec"
32
+ spec.add_development_dependency "rspec-nc"
33
+ spec.add_development_dependency "guard"
34
+ spec.add_development_dependency "guard-rspec"
35
+ spec.add_development_dependency "pry"
36
+ spec.add_development_dependency "pry-remote"
37
+ spec.add_development_dependency "pry-nav"
38
+ spec.add_development_dependency "coveralls"
39
+
40
+ spec.add_runtime_dependency "crimp"
41
+ end
@@ -0,0 +1,66 @@
1
+ require 'benchmark'
2
+ require 'logger'
3
+
4
+ require 'hetzner-api'
5
+ require 'hetzner/boot/freebsd/version'
6
+ require 'hetzner/boot/freebsd/target'
7
+
8
+ module Hetzner
9
+ module Boot
10
+ class FreeBSD
11
+ attr_accessor :targets
12
+ attr_accessor :api
13
+ attr_accessor :actions
14
+ attr_accessor :logger
15
+
16
+ def initialize(options = {})
17
+ @targets = []
18
+ @actions = %w(
19
+ remove_from_local_known_hosts
20
+ enable_rescue_mode
21
+ reset
22
+ wait_for_ssh_down
23
+ wait_for_ssh_up
24
+ update_local_known_hosts
25
+ verify_installation
26
+ )
27
+ @api = options[:api]
28
+ @logger = options[:logger] || Logger.new(STDOUT)
29
+ end
30
+
31
+ def add_target(param)
32
+ if param.is_a? Hetzner::Boot::FreeBSD::Target
33
+ @targets << param
34
+ else
35
+ @targets << (Hetzner::Boot::FreeBSD::Target.new param)
36
+ end
37
+ end
38
+
39
+ def <<(param)
40
+ add_target param
41
+ end
42
+
43
+ def bootstrap!(options = {})
44
+ @targets.each do |target|
45
+ target.use_api @api
46
+ target.use_logger @logger
47
+ bootstrap_one_target! target
48
+ end
49
+ end
50
+
51
+ def bootstrap_one_target!(target)
52
+ actions = (target.actions || @actions)
53
+ actions.each_with_index do |action, index|
54
+ loghack = "\b" * 24 # remove: "[bootstrap_one_target!] ".length
55
+ target.logger.info "#{loghack}[#{action}] #{sprintf "%-20s", "START"}"
56
+ d = Benchmark.realtime do
57
+ target.send action
58
+ end
59
+ target.logger.info "#{loghack}[#{action}] FINISHED in #{sprintf "%.5f",d} seconds"
60
+ end
61
+ rescue => e
62
+ target.logger.error "Something bad happened unexpectedly: #{e.class} => #{e.message}"
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,189 @@
1
+ require 'erubis'
2
+ require 'net/ssh'
3
+ require 'socket'
4
+ require 'timeout'
5
+ require 'colorize'
6
+
7
+ module Hetzner
8
+ module Boot
9
+ class FreeBSD
10
+ class Target
11
+ attr_accessor :ip
12
+ attr_accessor :login
13
+ attr_accessor :password
14
+ attr_accessor :rescue_os
15
+ attr_accessor :rescue_os_bit
16
+ attr_accessor :actions
17
+ attr_accessor :hostname
18
+ attr_accessor :post_install
19
+ attr_accessor :post_install_remote
20
+ attr_accessor :public_keys
21
+ attr_accessor :bootstrap_cmd
22
+ attr_accessor :logger
23
+
24
+ def initialize(options = {})
25
+ @rescue_os = 'freebsd'
26
+ @rescue_os_bit = '64'
27
+ @retries = 0
28
+ @login = 'root'
29
+
30
+ options.each_pair do |k,v|
31
+ self.send("#{k}=", v)
32
+ end
33
+ end
34
+
35
+ def enable_rescue_mode(options = {})
36
+ result = @api.enable_rescue! @ip, @rescue_os, @rescue_os_bit
37
+ if result.success? && result['rescue']
38
+ @password = result['rescue']['password']
39
+ reset_retries
40
+ logger.info "IP: #{ip} | username: #{@login} | password: #{@password}".colorize(:magenta)
41
+ elsif @retries > 3
42
+ logger.error "Rescue system could not be activated".colorize(:red)
43
+ raise CantActivateRescueSystemError, result
44
+ else
45
+ @retries += 1
46
+
47
+ logger.warn "Problem while trying to activate rescue system (retries: #{@retries})".colorize(:yellow)
48
+ @api.disable_rescue! @ip
49
+
50
+ rolling_sleep
51
+ enable_rescue_mode options
52
+ end
53
+ end
54
+
55
+ def reset(options = {})
56
+ result = @api.reset! @ip, :hw
57
+
58
+ if result.success?
59
+ reset_retries
60
+ elsif @retries > 3
61
+ logger.error "Resetting through web service failed.".colorize(:red)
62
+ raise CantResetSystemError, result
63
+ else
64
+ @retries += 1
65
+ logger.warn "Problem while trying to reset/reboot system (retries: #{@retries})".colorize(:yellow)
66
+ rolling_sleep
67
+ reset options
68
+ end
69
+ end
70
+
71
+ def port_open? ip, port
72
+ ssh_port_probe = TCPSocket.new ip, port
73
+ IO.select([ssh_port_probe], nil, nil, 2)
74
+ ssh_port_probe.close
75
+ true
76
+ end
77
+
78
+ def wait_for_ssh_down(options = {})
79
+ loop do
80
+ sleep 2
81
+ Timeout::timeout(4) do
82
+ if port_open? @ip, 22
83
+ logger.debug "SSH UP".colorize(:magenta)
84
+ else
85
+ raise Errno::ECONNREFUSED
86
+ end
87
+ end
88
+ end
89
+ rescue Timeout::Error, Errno::ECONNREFUSED
90
+ logger.debug "SSH down".colorize(:magenta)
91
+ end
92
+
93
+ def wait_for_ssh_up(options = {})
94
+ loop do
95
+ Timeout::timeout(4) do
96
+ if port_open? @ip, 22
97
+ logger.debug "SSH up".colorize(:magenta)
98
+ return true
99
+ else
100
+ raise Errno::ECONNREFUSED
101
+ end
102
+ end
103
+ end
104
+ rescue Errno::ECONNREFUSED, Timeout::Error
105
+ logger.debug "SSH down".colorize(:magenta)
106
+ sleep 2
107
+ retry
108
+ end
109
+
110
+ def reboot(options = {})
111
+ logger.info "Rebooting ...".colorize(:magenta)
112
+ remote do |ssh|
113
+ ssh.exec!("reboot")
114
+ end
115
+ end
116
+
117
+ def verify_installation(options = {})
118
+ logger.info "Verifying the installation ...".colorize(:magenta)
119
+ #@login = 'root'
120
+ #remote(password: nil) do |ssh|
121
+ # working_hostname = ssh.exec!("cat /etc/hostname")
122
+ # if @hostname == working_hostname.chomp
123
+ # logger.info "The installation has been successful".colorize(:green)
124
+ # else
125
+ # raise InstallationError, "Hostnames do not match: assumed #{@hostname} but received #{working_hostname}"
126
+ # end
127
+ #end
128
+ end
129
+
130
+ def remove_from_local_known_hosts(options = {})
131
+ `ssh-keygen -R #{@hostname}`
132
+ `ssh-keygen -R #{@ip}`
133
+ end
134
+
135
+ def update_local_known_hosts(options = {})
136
+ remote do |ssh|
137
+ logger.info "Removing SSH keys for #{@hostname} from local ~/.ssh/known_hosts file ...".colorize(:magenta)
138
+ `ssh-keygen -R #{@hostname}`
139
+ `ssh-keygen -R #{@ip}`
140
+ end
141
+ rescue Net::SSH::HostKeyMismatch => e
142
+ e.remember_host!
143
+ logger.info "Remote host key has been added to local ~/.ssh/known_hosts file.".colorize(:green)
144
+ end
145
+
146
+ def use_api(api_obj)
147
+ @api = api_obj
148
+ end
149
+
150
+ def use_logger(logger_obj)
151
+ @logger = logger_obj
152
+ @logger.formatter = default_log_formatter
153
+ end
154
+
155
+ def remote(options = {}, &block)
156
+ default = { :password => @password }
157
+ default.merge! options
158
+ Net::SSH.start(@ip, @login, default) do |ssh|
159
+ block.call ssh
160
+ end
161
+ end
162
+
163
+ def local(&block)
164
+ block.call
165
+ end
166
+
167
+ def reset_retries
168
+ @retries = 0
169
+ end
170
+
171
+ def rolling_sleep
172
+ sleep @retries * @retries * 3 + 1 # => 1, 4, 13, 28, 49, 76, 109, 148, 193, 244, 301, 364 ... seconds
173
+ end
174
+
175
+ def default_log_formatter
176
+ proc do |severity, datetime, progname, msg|
177
+ caller[4]=~/`(.*?)'/
178
+ "[#{datetime.strftime "%H:%M:%S"}][#{sprintf "%-15s", ip}][#{$1}] #{msg}\n"
179
+ end
180
+ end
181
+
182
+ class CantActivateRescueSystemError < StandardError; end
183
+ class CantResetSystemError < StandardError; end
184
+ class InstallationError < StandardError; end
185
+ end
186
+ end
187
+ end
188
+ end
189
+
@@ -0,0 +1,8 @@
1
+ module Hetzner
2
+ module Boot
3
+ class FreeBSD
4
+ VERSION = '0.0.2'
5
+ end
6
+ end
7
+ end
8
+
@@ -0,0 +1,28 @@
1
+ require 'hetzner-api'
2
+ require 'spec_helper'
3
+
4
+ describe "Bootstrap" do
5
+ before(:all) do
6
+ @api = Hetzner::API.new ENV['HETZNER_ROBOT_USERNAME'], ENV['HETZNER_ROBOT_PASSWORD']
7
+ @bootstrap = Hetzner::Boot::FreeBSD.new :api => @api
8
+ end
9
+
10
+ describe ".add_target(target)" do
11
+ it "should be able to add a server to operate on" do
12
+ @bootstrap.add_target dummy_target
13
+ expect(@bootstrap.targets.size).to equal(1)
14
+ expect(@bootstrap.targets.first).to be_an_instance_of(Hetzner::Boot::FreeBSD::Target)
15
+ end
16
+ end
17
+
18
+ def dummy_target
19
+ return {
20
+ :ip => "1.2.3.4",
21
+ :login => "MyHetznerUsername",
22
+ :password => "MyVerySecretPW",
23
+ :rescue_os => "freebsd",
24
+ :rescue_os_bit => "64"
25
+ }
26
+ end
27
+
28
+ end
@@ -0,0 +1,6 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+ require 'pry'
4
+ require 'dotenv'
5
+ Dotenv.load
6
+ require 'hetzner-boot-freebsd'
metadata ADDED
@@ -0,0 +1,299 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hetzner-boot-freebsd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Christoph Pilka
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hetzner-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: net-ssh
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.9.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.9.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: erubis
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.7.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.7.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: colorize
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.7.5
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.7.5
69
+ - !ruby/object:Gem::Dependency
70
+ name: highline
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.7.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.7.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: dotenv
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 2.0.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 2.0.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.5'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.5'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec-nc
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: guard
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: guard-rspec
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: pry
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: pry-remote
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: pry-nav
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: coveralls
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: crimp
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ description: Allows to reboot a physical server hosted at Hetzner into a minimal FreeBSD
252
+ recscue environment taht is based on mfsBSD.
253
+ email:
254
+ - c.pilka@asconix.com
255
+ executables: []
256
+ extensions: []
257
+ extra_rdoc_files: []
258
+ files:
259
+ - ".gitignore"
260
+ - ".ruby-gemset"
261
+ - ".ruby-version"
262
+ - Gemfile
263
+ - LICENSE
264
+ - README.md
265
+ - Rakefile
266
+ - example.rb
267
+ - hetzner-boot-freebsd.gemspec
268
+ - lib/hetzner-boot-freebsd.rb
269
+ - lib/hetzner/boot/freebsd/target.rb
270
+ - lib/hetzner/boot/freebsd/version.rb
271
+ - spec/hetzner-boot-freebsd_spec.rb
272
+ - spec/spec_helper.rb
273
+ homepage: http://www.asconix.com
274
+ licenses:
275
+ - BSD-3
276
+ metadata: {}
277
+ post_install_message:
278
+ rdoc_options: []
279
+ require_paths:
280
+ - lib
281
+ required_ruby_version: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ required_rubygems_version: !ruby/object:Gem::Requirement
287
+ requirements:
288
+ - - ">="
289
+ - !ruby/object:Gem::Version
290
+ version: '0'
291
+ requirements: []
292
+ rubyforge_project:
293
+ rubygems_version: 2.4.5
294
+ signing_key:
295
+ specification_version: 4
296
+ summary: Reboot a Hetzner server into FreeBSD rescue environment
297
+ test_files:
298
+ - spec/hetzner-boot-freebsd_spec.rb
299
+ - spec/spec_helper.rb