Module: AmoebaDeployTools::Concerns::SSH

Included in:
Node, Ssl
Defined in:
lib/amoeba_deploy_tools/commands/concerns/ssh.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



4
5
6
# File 'lib/amoeba_deploy_tools/commands/concerns/ssh.rb', line 4

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#knife_solo(cmd, options = {}) {|json| ... } ⇒ Object

Run knife solo command on server

Yields:

  • (json)


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
78
79
80
# File 'lib/amoeba_deploy_tools/commands/concerns/ssh.rb', line 32

def knife_solo(cmd, options={})
  say_fatal 'ERROR: Node must have a name defined' unless node.name

  # Ensure json is a hashie
  json = options.delete(:json) || Hashie::Mash.new

  # If a block is specified, it means we have json in it, so let's resolve it
  yield(json) if block_given?

  # Ensure JSON for the node is set. It is either provided by the calling party, or we use the
  # node file's definitions.
  if json.empty?
    json.deep_merge!(node)
  end

  exec = "bundle exec knife solo #{cmd.to_s} "

  if options.delete(:ssh)
    exec << node_host_args(port: '--ssh-port',
                           config: '--ssh-config-file',
                           ident: '--identity-file') << ' '
    exec << "--no-host-key-verify --node-name #{node.name}"
  end

  if options.delete(:include_private_key)
    private_key = node.private_key || 'default'
    private_key = config.private_keys_[private_key]

    # Stick the private key into a our custom JSON (to be appended to the node)
    json.private_key_raw = private_key if private_key
  end

  opts = {}
  opts[:runner] = AmoebaDeployTools::InteractiveCocaineRunner.new if options.delete(:interactive)

  # Now go through all the options specified and append them to args
  args = ''
  options.each do |argument, value|
    args << " --#{argument} #{value}"
  end

  inside_kitchen do
    # JSON will be written to a temp file and used in place of the node JSON file
    with_tmpfile(JSON.dump(json), name: ['node', '.json']) do |file_name|
      knife_solo_cmd = Cocaine::CommandLine.new(exec, "#{args} #{file_name}", opts)
      knife_solo_cmd.run
    end
  end
end

#node_host_args(flag_map) ⇒ Object

Outputs SSH options for connecting to this node (provide a map of deploy key to command line arg name).



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/amoeba_deploy_tools/commands/concerns/ssh.rb', line 16

def node_host_args(flag_map)
  say_fatal 'ERROR: Missing deployment info for node.' unless deployment && deployment.host

  host_arg = deployment.host
  host_arg = "#{deployment.user}@#{host_arg}" if deployment.user

  # Iterate through all the specified flags and check if they're defined in the deployment
  # config, appending them to the output if they are.
  flag_map.each do |field, argument_name|
    host_arg << " #{argument_name} #{deployment[field]}" if deployment[field]
  end

  host_arg
end

#ssh_run(cmd, options) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/amoeba_deploy_tools/commands/concerns/ssh.rb', line 82

def ssh_run(cmd, options)
  options = {
    silent: false,
    interactive: false
  }.merge!(options)

  opts = {}
  opts[:runner] = Cocaine::CommandLine::BackticksRunner.new if options[:silent]
  opts[:runner] = AmoebaDeployTools::InteractiveCocaineRunner.new if options[:interactive]

  ssh_cmd = node_host_args(port: '-p', ident: '-i')

  [ 'Compression=yes',
    'DSAAuthentication=yes',
    'LogLevel=FATAL',
    'StrictHostKeyChecking=no',
    'UserKnownHostsFile=/dev/null'
  ].each do |opt|
    ssh_cmd << " -o #{opt}"
  end

  ssh_cmd << " '#{cmd}'" if cmd && !cmd.empty?

  Cocaine::CommandLine.new('ssh', ssh_cmd, opts).run
end