Class: SSHKit::Backend::Netssh

Inherits:
Object
  • Object
show all
Defined in:
lib/cronicle/ext/sshkit_ext.rb

Constant Summary collapse

SUDO_PASSWORD_KEY =
:'__cronicle_sudo_password__'
SUDO_PROMPT =
'__cronicle_sudo_prompt__'
CRON_DIRS =
%w(/var/spool/cron/crontabs /var/spool/cron)
BUNDLER_PATHS =
%w(
  /usr/local/bin/bundle
  /usr/bin/bundle
)

Instance Method Summary collapse

Instance Method Details

#_execute(*args) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/cronicle/ext/sshkit_ext.rb', line 13

def _execute(*args)
  options = args.last.kind_of?(Hash) ? args.last : {}
  orig_output = output

  begin
    if options[:sniffer]
      @output = Cronicle::LogSniffer.new(orig_output) do |obj|
        options[:sniffer].call(obj)
      end
    end

    _execute_orig(*args)
  rescue => e
    log_for_cronicle(:error, args.join(' '), :color => :red)
    raise e
  ensure
    @output = orig_output
  end
end

#_execute_origObject



7
# File 'lib/cronicle/ext/sshkit_ext.rb', line 7

alias _execute_orig _execute

#add_cron_entry(user, name, schedule, temp_dir, bundle_gems = nil) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/cronicle/ext/sshkit_ext.rb', line 104

def add_cron_entry(user, name, schedule, temp_dir, bundle_gems = nil)
  script = script_path(user, name)
  temp_entry = [temp_dir, name + '.entry'].join('/')

  cron_entry = "#{schedule}\\t"

  if bundle_gems
    cron_entry << "cd #{gemfile_dir(user, name)} && #{bundler_path} exec "
  end

  cron_entry << "#{script} 2>&1 | logger -t cronicle/#{user}/#{name}"
  cron_entry = Shellwords.shellescape(cron_entry)
  sudo(:execute, :echo, '-e', cron_entry, '>', temp_entry)

  entry_cat = "cat #{temp_entry} >> #{user_crontab(user)}"
  entry_cat = Shellwords.shellescape(entry_cat)
  sudo(:execute, :bash, '-c', entry_cat)
end

#bundle(user, name, temp_dir = nil) ⇒ Object



169
170
171
172
173
174
175
# File 'lib/cronicle/ext/sshkit_ext.rb', line 169

def bundle(user, name, temp_dir = nil)
  with_bundle(user, name, temp_dir) do |bundler_opts|
    unless sudo(:execute, bundler_path, :check, *bundler_opts, :raise_on_non_zero_exit => false)
      sudo(:execute, bundler_path, :install, *bundler_opts)
    end
  end
end

#bundle_dirObject



192
193
194
# File 'lib/cronicle/ext/sshkit_ext.rb', line 192

def bundle_dir
  host.options.fetch(:var_dir) + '/bundle'
end

#bundler_pathObject



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/cronicle/ext/sshkit_ext.rb', line 201

def bundler_path
  @bundler_path ||= BUNDLER_PATHS.find {|path|
    execute(:test, '-f', path, :raise_on_non_zero_exit => false)
  }

  path = capture(:which, :bundle, '2>', '/dev/null', :raise_on_non_zero_exit => false) || ''
  path.strip!

  if path.empty?
    log_for_cronicle(:error, 'cannot find bundler', :color => :red, :host => host.hostname)
  else
    @bundler_path = path
  end

  @bundler_path
end

#delete_cron_entry(user, name = nil) ⇒ Object



97
98
99
100
101
102
# File 'lib/cronicle/ext/sshkit_ext.rb', line 97

def delete_cron_entry(user, name = nil)
  sed_cmd = '/' + Cronicle::Utils.sed_escape(script_path(user, name)) + ' /d'
  sed_cmd = Shellwords.shellescape(sed_cmd)

  sudo(:execute, :sed, '-i', sed_cmd, user_crontab(user), :raise_on_non_zero_exit => false)
end

#fetch_crontabsObject



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cronicle/ext/sshkit_ext.rb', line 68

def fetch_crontabs
  return @crontabs if @crontabs

  @crontabs = {}

  list_crontabs.each do |path|
    user = File.basename(path)
    crontab = sudo(:capture, :cat, path)
    @crontabs[user] = crontab
  end

  @crontabs
end

#fetch_libexec_scriptsObject



87
88
89
90
91
92
93
94
95
# File 'lib/cronicle/ext/sshkit_ext.rb', line 87

def fetch_libexec_scripts
  script_contents = {}

  list_libexec_scripts.each do |script|
    script_contents[script] = crlf_to_lf(capture(:cat, script))
  end

  script_contents
end

#find_cron_dirObject



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/cronicle/ext/sshkit_ext.rb', line 49

def find_cron_dir
  @cron_dir ||= CRON_DIRS.find do |path|
    execute(:test, '-d', path, :raise_on_non_zero_exit => false)
  end

  unless @cron_dir
    raise "Cannot find cron directory: #{CRON_DIRS.join(', ')}"
  end

  @cron_dir
end

#gemfile(user, name, temp_dir = nil) ⇒ Object



234
235
236
# File 'lib/cronicle/ext/sshkit_ext.rb', line 234

def gemfile(user, name, temp_dir = nil)
  [gemfile_dir(user, name, temp_dir), 'Gemfile'].join('/')
end

#gemfile_dir(user, name, temp_dir = nil) ⇒ Object



226
227
228
229
230
231
232
# File 'lib/cronicle/ext/sshkit_ext.rb', line 226

def gemfile_dir(user, name, temp_dir = nil)
  if temp_dir
    [temp_dir, user, name].join('/')
  else
    [user_run_dir(user), name].join('/')
  end
end

#libexec_dirObject



184
185
186
# File 'lib/cronicle/ext/sshkit_ext.rb', line 184

def libexec_dir
  host.options.fetch(:var_dir) + '/libexec'
end

#list_crontabsObject



61
62
63
64
65
66
# File 'lib/cronicle/ext/sshkit_ext.rb', line 61

def list_crontabs
  cron_dir = find_cron_dir
  @crontab_list ||= sudo(:capture, :bash, '-c',
                      Shellwords.shellescape("find #{cron_dir} -type f 2> /dev/null"),
                      :raise_on_non_zero_exit => false).each_line.map(&:strip)
end

#list_libexec_scriptsObject



82
83
84
85
# File 'lib/cronicle/ext/sshkit_ext.rb', line 82

def list_libexec_scripts
  @libexec_scripts ||= capture(:find, libexec_dir, '-type', :f, '2> /dev/null',
                         :raise_on_non_zero_exit => false).each_line.map(&:strip)
end

#log_for_cronicle(level, message, opts = {}) ⇒ Object



247
248
249
250
# File 'lib/cronicle/ext/sshkit_ext.rb', line 247

def log_for_cronicle(level, message, opts = {})
  opts = host.options.merge(opts)
  Cronicle::Logger.log(level, message, opts)
end

#mkgemfile(user, name, bundle_gems, temp_dir = nil) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/cronicle/ext/sshkit_ext.rb', line 150

def mkgemfile(user, name, bundle_gems, temp_dir = nil)
  sudo(:execute, :mkdir, '-p', gemfile_dir(user, name, temp_dir))
  sudo(:execute, :bash, '-c',
    Shellwords.shellescape(
      [:echo, Shellwords.shellescape("source 'https://rubygems.org'"), '>', gemfile(user, name, temp_dir)].join(' ')
    )
  )

  bundle_gems.each do |gem_name, version|
    line = "gem '#{gem_name}'"
    line << ", #{version.inspect}" if version
    sudo(:execute, :bash, '-c',
      Shellwords.shellescape(
        [:echo, Shellwords.shellescape(line), '>>', gemfile(user, name, temp_dir)].join(' ')
      )
    )
  end
end

#mktemp(user = nil) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/cronicle/ext/sshkit_ext.rb', line 130

def mktemp(user = nil)
  temp_dir = capture(:mktemp, '-d', '/var/tmp/cronicle.XXXXXXXXXX')
  block_args = [temp_dir]

  begin
    execute(:chmod, 755, temp_dir)

    if user
      user_temp_dir = [temp_dir, user].join('/')
      execute(:mkdir, '-p', user_temp_dir)
      execute(:chmod, 755, user_temp_dir)
      block_args << user_temp_dir
    end

    yield(*block_args)
  ensure
    sudo(:execute, :rm, '-rf', temp_dir, :raise_on_non_zero_exit => false) rescue nil
  end
end

#outputObject



9
10
11
# File 'lib/cronicle/ext/sshkit_ext.rb', line 9

def output
  @output ||= SSHKit.config.output
end

#run_dirObject



188
189
190
# File 'lib/cronicle/ext/sshkit_ext.rb', line 188

def run_dir
  host.options.fetch(:var_dir) + '/run'
end

#script_path(user, name) ⇒ Object



243
244
245
# File 'lib/cronicle/ext/sshkit_ext.rb', line 243

def script_path(user, name)
  [libexec_dir, user, name].join('/')
end

#sudo(command, *args) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/cronicle/ext/sshkit_ext.rb', line 33

def sudo(command, *args)
  opts = args.last.kind_of?(Hash) ? args.pop : {}

  retval = with_sudo_password(host.options[:sudo_password] || '') do
    with_sudo = [:sudo, '-p', SUDO_PROMPT, '-S']
    with_sudo << :sudo << '-u' << opts[:user] if opts[:user]
    with_sudo.concat(args)
    send(command, *with_sudo, opts)
  end

  Cronicle::Utils.remove_prompt!(retval) if retval.kind_of?(String)
  retval
end

#upload_script(temp_dir, name, content) {|temp_script| ... } ⇒ Object

Yields:

  • (temp_script)


123
124
125
126
127
128
# File 'lib/cronicle/ext/sshkit_ext.rb', line 123

def upload_script(temp_dir, name, content)
  temp_script = [temp_dir, name].join('/')
  upload!(StringIO.new(content), temp_script)
  execute(:chmod, 755, temp_script)
  yield(temp_script)
end

#user_crontab(user) ⇒ Object



238
239
240
241
# File 'lib/cronicle/ext/sshkit_ext.rb', line 238

def user_crontab(user)
  cron_dir = find_cron_dir
  [cron_dir, user].join('/')
end

#user_libexec_dir(user) ⇒ Object



218
219
220
# File 'lib/cronicle/ext/sshkit_ext.rb', line 218

def user_libexec_dir(user)
  [libexec_dir, user].join('/')
end

#user_run_dir(user) ⇒ Object



222
223
224
# File 'lib/cronicle/ext/sshkit_ext.rb', line 222

def user_run_dir(user)
  [run_dir, user].join('/')
end

#with_bundle(user, name, temp_dir = nil) ⇒ Object



177
178
179
180
181
182
# File 'lib/cronicle/ext/sshkit_ext.rb', line 177

def with_bundle(user, name, temp_dir = nil)
  within gemfile_dir(user, name, temp_dir) do
    bundler_opts = ['--no-color', '--gemfile', gemfile(user, name, temp_dir), '--path', bundle_dir]
    yield(bundler_opts)
  end
end