Class: Hetzner::Boot::FreeBSD::Target

Inherits:
Object
  • Object
show all
Defined in:
lib/hetzner/boot/freebsd/target.rb

Defined Under Namespace

Classes: CantActivateRescueSystemError, CantResetSystemError, InstallationError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Target

Returns a new instance of Target.



24
25
26
27
28
29
30
31
32
33
# File 'lib/hetzner/boot/freebsd/target.rb', line 24

def initialize(options = {})
  @rescue_os     = 'freebsd'
  @rescue_os_bit = '64'
  @retries       = 0
  @login         = 'root'

  options.each_pair do |k,v|
    self.send("#{k}=", v)
  end
end

Instance Attribute Details

#actionsObject

Returns the value of attribute actions.



16
17
18
# File 'lib/hetzner/boot/freebsd/target.rb', line 16

def actions
  @actions
end

#bootstrap_cmdObject

Returns the value of attribute bootstrap_cmd.



21
22
23
# File 'lib/hetzner/boot/freebsd/target.rb', line 21

def bootstrap_cmd
  @bootstrap_cmd
end

#hostnameObject

Returns the value of attribute hostname.



17
18
19
# File 'lib/hetzner/boot/freebsd/target.rb', line 17

def hostname
  @hostname
end

#ipObject

Returns the value of attribute ip.



11
12
13
# File 'lib/hetzner/boot/freebsd/target.rb', line 11

def ip
  @ip
end

#loggerObject

Returns the value of attribute logger.



22
23
24
# File 'lib/hetzner/boot/freebsd/target.rb', line 22

def logger
  @logger
end

#loginObject

Returns the value of attribute login.



12
13
14
# File 'lib/hetzner/boot/freebsd/target.rb', line 12

def 
  @login
end

#passwordObject

Returns the value of attribute password.



13
14
15
# File 'lib/hetzner/boot/freebsd/target.rb', line 13

def password
  @password
end

#post_installObject

Returns the value of attribute post_install.



18
19
20
# File 'lib/hetzner/boot/freebsd/target.rb', line 18

def post_install
  @post_install
end

#post_install_remoteObject

Returns the value of attribute post_install_remote.



19
20
21
# File 'lib/hetzner/boot/freebsd/target.rb', line 19

def post_install_remote
  @post_install_remote
end

#public_keysObject

Returns the value of attribute public_keys.



20
21
22
# File 'lib/hetzner/boot/freebsd/target.rb', line 20

def public_keys
  @public_keys
end

#rescue_osObject

Returns the value of attribute rescue_os.



14
15
16
# File 'lib/hetzner/boot/freebsd/target.rb', line 14

def rescue_os
  @rescue_os
end

#rescue_os_bitObject

Returns the value of attribute rescue_os_bit.



15
16
17
# File 'lib/hetzner/boot/freebsd/target.rb', line 15

def rescue_os_bit
  @rescue_os_bit
end

Instance Method Details

#default_log_formatterObject



175
176
177
178
179
180
# File 'lib/hetzner/boot/freebsd/target.rb', line 175

def default_log_formatter
   proc do |severity, datetime, progname, msg|
     caller[4]=~/`(.*?)'/
     "[#{datetime.strftime "%H:%M:%S"}][#{sprintf "%-15s", ip}][#{$1}] #{msg}\n"
   end
end

#enable_rescue_mode(options = {}) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/hetzner/boot/freebsd/target.rb', line 35

def enable_rescue_mode(options = {})
  result = @api.enable_rescue! @ip, @rescue_os, @rescue_os_bit
  if result.success? && result['rescue']
    @password = result['rescue']['password']
    reset_retries
    logger.info "IP: #{ip} | username: #{@login} | password: #{@password}".colorize(:magenta)
  elsif @retries > 3
    logger.error "Rescue system could not be activated".colorize(:red)
    raise CantActivateRescueSystemError, result
  else
    @retries += 1

    logger.warn "Problem while trying to activate rescue system (retries: #{@retries})".colorize(:yellow)
    @api.disable_rescue! @ip

    rolling_sleep
    enable_rescue_mode options
  end
end

#local(&block) ⇒ Object



163
164
165
# File 'lib/hetzner/boot/freebsd/target.rb', line 163

def local(&block)
  block.call
end

#port_open?(ip, port) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
74
75
76
# File 'lib/hetzner/boot/freebsd/target.rb', line 71

def port_open? ip, port
  ssh_port_probe = TCPSocket.new ip, port
  IO.select([ssh_port_probe], nil, nil, 2)
  ssh_port_probe.close
  true
end

#reboot(options = {}) ⇒ Object



110
111
112
113
114
115
# File 'lib/hetzner/boot/freebsd/target.rb', line 110

def reboot(options = {})
  logger.info "Rebooting ...".colorize(:magenta)
  remote do |ssh|
    ssh.exec!("reboot")
  end
end

#remote(options = {}, &block) ⇒ Object



155
156
157
158
159
160
161
# File 'lib/hetzner/boot/freebsd/target.rb', line 155

def remote(options = {}, &block)
  default = { :password => @password }
  default.merge! options
  Net::SSH.start(@ip, @login, default) do |ssh|
    block.call ssh
  end
end

#remove_from_local_known_hosts(options = {}) ⇒ Object



130
131
132
133
# File 'lib/hetzner/boot/freebsd/target.rb', line 130

def remove_from_local_known_hosts(options = {})
  `ssh-keygen -R #{@hostname}`
  `ssh-keygen -R #{@ip}`
end

#reset(options = {}) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/hetzner/boot/freebsd/target.rb', line 55

def reset(options = {})
  result = @api.reset! @ip, :hw

  if result.success?
    reset_retries
  elsif @retries > 3
    logger.error "Resetting through web service failed.".colorize(:red)
    raise CantResetSystemError, result
  else
    @retries += 1
    logger.warn "Problem while trying to reset/reboot system (retries: #{@retries})".colorize(:yellow)
    rolling_sleep
    reset options
  end
end

#reset_retriesObject



167
168
169
# File 'lib/hetzner/boot/freebsd/target.rb', line 167

def reset_retries
  @retries = 0
end

#rolling_sleepObject



171
172
173
# File 'lib/hetzner/boot/freebsd/target.rb', line 171

def rolling_sleep
  sleep @retries * @retries * 3 + 1 # => 1, 4, 13, 28, 49, 76, 109, 148, 193, 244, 301, 364 ... seconds
end

#update_local_known_hosts(options = {}) ⇒ Object



135
136
137
138
139
140
141
142
143
144
# File 'lib/hetzner/boot/freebsd/target.rb', line 135

def update_local_known_hosts(options = {})
  remote do |ssh|
    logger.info "Removing SSH keys for #{@hostname} from local ~/.ssh/known_hosts file ...".colorize(:magenta)
    `ssh-keygen -R #{@hostname}`
    `ssh-keygen -R #{@ip}`
  end
rescue Net::SSH::HostKeyMismatch => e
  e.remember_host!
  logger.info "Remote host key has been added to local ~/.ssh/known_hosts file.".colorize(:green)
end

#use_api(api_obj) ⇒ Object



146
147
148
# File 'lib/hetzner/boot/freebsd/target.rb', line 146

def use_api(api_obj)
  @api = api_obj
end

#use_logger(logger_obj) ⇒ Object



150
151
152
153
# File 'lib/hetzner/boot/freebsd/target.rb', line 150

def use_logger(logger_obj)
  @logger = logger_obj
  @logger.formatter = default_log_formatter
end

#verify_installation(options = {}) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/hetzner/boot/freebsd/target.rb', line 117

def verify_installation(options = {})
  logger.info "Verifying the installation ...".colorize(:magenta)
  #@login = 'root'
  #remote(password: nil) do |ssh|
  #  working_hostname = ssh.exec!("cat /etc/hostname")
  #  if @hostname == working_hostname.chomp
  #    logger.info "The installation has been successful".colorize(:green)
  #  else
  #    raise InstallationError, "Hostnames do not match: assumed #{@hostname} but received #{working_hostname}"
  #  end
  #end
end

#wait_for_ssh_down(options = {}) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/hetzner/boot/freebsd/target.rb', line 78

def wait_for_ssh_down(options = {})
  loop do
    sleep 2
    Timeout::timeout(4) do
      if port_open? @ip, 22
        logger.debug "SSH UP".colorize(:magenta)
      else
        raise Errno::ECONNREFUSED
      end
    end
  end
rescue Timeout::Error, Errno::ECONNREFUSED
  logger.debug "SSH down".colorize(:magenta)
end

#wait_for_ssh_up(options = {}) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/hetzner/boot/freebsd/target.rb', line 93

def wait_for_ssh_up(options = {})
  loop do
    Timeout::timeout(4) do
      if port_open? @ip, 22
        logger.debug "SSH up".colorize(:magenta)
        return true
      else
        raise Errno::ECONNREFUSED
      end
    end
  end
rescue Errno::ECONNREFUSED, Timeout::Error
  logger.debug "SSH down".colorize(:magenta)
  sleep 2
  retry
end