Module: Cirrus::SSH
Instance Method Summary collapse
-
#add_to_keychain(private_key_path) ⇒ Object
Start ssh-agent and add a key to the keychain TODO: avoid starting if already running.
-
#bootstrap(host:, username:, private_key_path:, source_path:) ⇒ Object
TODO: better key handling (bootstrap with public key).
-
#connect(host, username) {|connection| ... } ⇒ Object
Open an SSH connection and yield it.
Instance Method Details
#add_to_keychain(private_key_path) ⇒ Object
Start ssh-agent and add a key to the keychain TODO: avoid starting if already running
82 83 84 85 86 |
# File 'lib/cirrus/ssh.rb', line 82 def add_to_keychain(private_key_path) puts "Starting ssh-agent, adding keypair private key ..." puts `eval $(ssh-agent)` puts `ssh-add #{private_key_path}` end |
#bootstrap(host:, username:, private_key_path:, source_path:) ⇒ Object
TODO: better key handling (bootstrap with public key)
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/cirrus/ssh.rb', line 90 def bootstrap(host:, username:, private_key_path:, source_path:) return unless source_path puts "Bootstrapping instance (#{username}@#{host}) ..." add_to_keychain(private_key_path) tf = Tempfile.new('boxer-shell') tf.write(File.read(source_path)) tf.rewind source_path = tf.path dest_path = "/tmp/boxer-shell" Cirrus::SCP.connect(host, username) do |scp| scp.upload!(source_path, dest_path) end end |
#connect(host, username) {|connection| ... } ⇒ Object
Open an SSH connection and yield it
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/cirrus/ssh.rb', line 12 def connect(host, username) timeout = 15 common_connect_opts = { auth_methods: ["publickey"], forward_agent: false, port: 22, timeout: 15, user_known_hosts_file: [], verbose: :debug } begin connection = Timeout.timeout(timeout) do begin connect_opts = common_connect_opts.dup connect_opts[:logger] = Logger.new(StringIO.new) Net::SSH.start(host, username, connect_opts) end end rescue Errno::EACCES # This happens on connect() for unknown reasons yet... raise "eacces" rescue Errno::ETIMEDOUT, Timeout::Error # This happens if we continued to timeout when attempting to connect. if $retry_count < 3 $retry_count += 1 retry else raise "timeout" end rescue Net::SSH::AuthenticationFailed # This happens if authentication failed. We wrap the error in our # own exception. raise "authentication" rescue Net::SSH::Disconnect # This happens if the remote server unexpectedly closes the # connection. This is usually raised when SSH is running on the # other side but can't properly setup a connection. This is # usually a server-side issue. raise "disconnect" rescue Errno::ECONNREFUSED # This is raised if we failed to connect the max amount of times raise "econnrefused" rescue Errno::ECONNRESET # This is raised if we failed to connect the max number of times # due to an ECONNRESET. raise "econnreset" rescue Errno::EHOSTDOWN # This is raised if we get an ICMP DestinationUnknown error. raise "ehostdown" rescue Errno::EHOSTUNREACH # This is raised if we can't work out how to route traffic. raise "ehostunreach" rescue Net::SSH::Exception => e # This is an internal error in Net::SSH raise "internal net ssh error" rescue NotImplementedError # This is raised if a private key type that Net-SSH doesn't support # is used. Show a nicer error. raise "unsupported private key type" end yield connection end |