Module: Rye::Cmd

Included in:
Box
Defined in:
lib/rye/cmd.rb

Overview

Rye::Cmd

This class contains all of the shell command methods available to an instance of Rye::Box. For security and general safety, Rye only permits this whitelist of commands by default. However, you’re free to add methods with mixins.

require 'rye'
module Rye::Cmd
  def special(*args); run_command("/your/special/command", args); end
end

rbox = Rye::Box.new('somehost')
rbox.special        # => "special on somehost"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.add_command(meth, path = nil, *hard_args, &block) ⇒ Object

A helper for adding a command to Rye::Cmd.

  • meth the method name

  • path (optional) filesystem path for the given method

  • hard_args (optional) hardcoded arguments which are prepended to the argument list every time the method is called

An optional block can be provided which will be called instead of calling a system command.



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/rye/cmd.rb', line 344

def Cmd.add_command(meth, path=nil, *hard_args, &block)
  if block
    hard_args.unshift(path) unless path.nil? # Don't lose an argument
    define_method(meth) do |*args|
      local_args = hard_args.clone
      local_args += args
      block.call(*local_args)
    end
  else
    path ||= meth.to_s
    define_method(meth) do |*args|
      local_args = hard_args.clone
      local_args += args
      run_command(path, *local_args)
    end        
  end
end

.can?(meth) ⇒ Boolean

Returns:

  • (Boolean)


333
334
335
# File 'lib/rye/cmd.rb', line 333

def Cmd.can?(meth)
  instance_methods.member?(meth)
end

.remove_command(meth) ⇒ Object

A helper for removing a command from Rye::Cmd.

  • meth the method name



364
365
366
# File 'lib/rye/cmd.rb', line 364

def Cmd.remove_command(meth)
  remove_method(meth)
end

Instance Method Details

#ab(*args) ⇒ Object



63
# File 'lib/rye/cmd.rb', line 63

def ab(*args) run_command('ab', args) end

#aptitude(*args) ⇒ Object



123
# File 'lib/rye/cmd.rb', line 123

def aptitude(*args) run_command('aptitude', args) end

#awk(*args) ⇒ Object



74
# File 'lib/rye/cmd.rb', line 74

def awk(*args) run_command('awk', args) end

#bash(*args, &blk) ⇒ Object

When called without a block this will open an interactive shell session.



33
34
35
36
# File 'lib/rye/cmd.rb', line 33

def bash(*args, &blk)
  setenv('PS1', "(rye) \\h:\\w \\u\\$\ ")
  __shell 'bash', *args, &blk
end

#bunzip2(*args) ⇒ Object



118
# File 'lib/rye/cmd.rb', line 118

def bunzip2(*args) run_command('bunzip2', args) end

#bzip2(*args) ⇒ Object



105
# File 'lib/rye/cmd.rb', line 105

def bzip2(*args) run_command('bzip2', args) end

#canObject Also known as: commands, cmds

Returns an Array of system commands available over SSH



321
322
323
# File 'lib/rye/cmd.rb', line 321

def can
  Rye::Cmd.instance_methods
end

#can?(meth) ⇒ Boolean

Returns:

  • (Boolean)


327
328
329
# File 'lib/rye/cmd.rb', line 327

def can?(meth)
  self.can.member?(RUBY_VERSION =~ /1.9/ ? meth.to_sym : meth.to_s)
end

#cat(*args) ⇒ Object



75
# File 'lib/rye/cmd.rb', line 75

def cat(*args) run_command('cat', args) end

#chmod(*args) ⇒ Object



102
# File 'lib/rye/cmd.rb', line 102

def chmod(*args) run_command('chmod', args) end

#chown(*args) ⇒ Object



103
# File 'lib/rye/cmd.rb', line 103

def chown(*args) run_command('chown', args) end

#cmd?Boolean

Returns:

  • (Boolean)


331
332
333
# File 'lib/rye/cmd.rb', line 331

def can?(meth)
  self.can.member?(RUBY_VERSION =~ /1.9/ ? meth.to_sym : meth.to_s)
end

#command?Boolean

Returns:

  • (Boolean)


330
331
332
# File 'lib/rye/cmd.rb', line 330

def can?(meth)
  self.can.member?(RUBY_VERSION =~ /1.9/ ? meth.to_sym : meth.to_s)
end

#configure(*args) ⇒ Object



130
# File 'lib/rye/cmd.rb', line 130

def configure(*args) run_command('./configure', args) end

#cp(*args) ⇒ Object



55
# File 'lib/rye/cmd.rb', line 55

def cp(*args) run_command("cp", args) end

#curl(*args) ⇒ Object



92
# File 'lib/rye/cmd.rb', line 92

def curl(*args) run_command('curl', args) end

#cvs(*args) ⇒ Object



71
# File 'lib/rye/cmd.rb', line 71

def cvs(*args) run_command('cvs', args) end

#date(*args) ⇒ Object



82
# File 'lib/rye/cmd.rb', line 82

def date(*args) run_command('date', args) end

#df(*args) ⇒ Object



59
# File 'lib/rye/cmd.rb', line 59

def df(*args) run_command('df', args) end

#digest_md5(*files) ⇒ Object

  • files An Array of file paths

Returns an Array of MD5 digests for each of the given files



298
299
300
301
302
# File 'lib/rye/cmd.rb', line 298

def digest_md5(*files)
  files.flatten.collect { |file| 
    File.exists?(file) ? Digest::MD5.hexdigest(File.read(file)) : nil
  }
end

#digest_sha1(*files) ⇒ Object

  • files An Array of file paths

Returns an Array of SH1 digests for each of the given files



306
307
308
309
310
# File 'lib/rye/cmd.rb', line 306

def digest_sha1(*files)
  files.flatten.collect { |file| 
    File.exists?(file) ? Digest::SHA1.hexdigest(File.read(file)) : nil
  }
end

#digest_sha2(*files) ⇒ Object

  • files An Array of file paths

Returns an Array of SH2 digests for each of the given files



314
315
316
317
318
# File 'lib/rye/cmd.rb', line 314

def digest_sha2(*files)
  files.flatten.collect { |file| 
    File.exists?(file) ? Digest::SHA2.hexdigest(File.read(file)) : nil
  }
end

#dir(*args) ⇒ Object

– WINDOWS ++



135
# File 'lib/rye/cmd.rb', line 135

def dir(*args); run_command('cmd', args); end

#dir_download(*paths) ⇒ Object Also known as: directory_download

Same as file_download except directories are processed recursively. If any supplied paths are directories you need to use this method and not file_download.



172
# File 'lib/rye/cmd.rb', line 172

def dir_download(*paths); net_scp_transfer!(:download, true, *paths); end

#dir_upload(*paths) ⇒ Object Also known as: directory_upload

Same as file_upload except directories are processed recursively. If any supplied paths are directories you need to use this method and not file_upload.



166
# File 'lib/rye/cmd.rb', line 166

def dir_upload(*paths); net_scp_transfer!(:upload, true, *paths); end

#dpkg(*args) ⇒ Object



93
# File 'lib/rye/cmd.rb', line 93

def dpkg(*args) run_command('dpkg', args) end

#du(*args) ⇒ Object



60
# File 'lib/rye/cmd.rb', line 60

def du(*args) run_command('du', args) end

#echo(*args) ⇒ Object



86
# File 'lib/rye/cmd.rb', line 86

def echo(*args) run_command('echo', args) end

#envObject



67
# File 'lib/rye/cmd.rb', line 67

def env()      run_command('env')       end

#file_append(filepath, newcontent, backup = false) ⇒ Object

Append newcontent to remote filepath. If the file doesn’t exist it will be created. If backup is specified, filepath will be copied to filepath-previous before appending.

NOTE: Not recommended for large files. It downloads the contents.



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/rye/cmd.rb', line 204

def file_append(filepath, newcontent, backup=false)
  content = StringIO.new
  
  if self.file_exists?(filepath)
    self.cp filepath, "#{filepath}-previous" if backup
    content = self.file_download filepath
  end
  
  if newcontent.is_a?(StringIO)
    newcontent.rewind
    content.puts newcontent.read
  else
    content.puts newcontent
  end
  
  self.file_upload content, filepath
end

#file_download(*paths) ⇒ Object

Transfer files from a machine via Net::SCP.

  • paths is an Array of files to download. The last element must be the

local directory to download to. If downloading a single file the last element can be a file path. The target can also be a StringIO object. The target directory will be created if it does not exist, but only when multiple files are being transferred. This method will fail early if there are obvious problems with the input parameters. An exception is raised and no files are transferred. Return nil or a StringIO object, if specified as the target.

NOTE: Changes to current working directory with cd or [] are ignored.



161
# File 'lib/rye/cmd.rb', line 161

def file_download(*paths); net_scp_transfer!(:download, false, *paths); end

#file_exists?(path) ⇒ Boolean

Does path from the current working directory?

Returns:

  • (Boolean)


274
275
276
277
278
279
280
281
282
283
# File 'lib/rye/cmd.rb', line 274

def file_exists?(path)
  begin
    ret = self.quietly { ls(path) }
  rescue Rye::Err => ex
    ret = ex.rap
  end
  # "ls" returns a 0 exit code regardless of success in Linux
  # But on OSX exit code is 1. This is why we look at STDERR. 
  !(ret.exit_status > 0) || ret.stderr.empty?
end

#file_modify(filepath, regexp, replace = nil) ⇒ Object



268
269
270
271
# File 'lib/rye/cmd.rb', line 268

def file_modify(filepath, regexp, replace=nil)
  raise "File not found: #{filepath}" unless file_exists?(filepath)
  sed :i, :r, "s/#{regexp}/#{replace}/", filepath
end

#file_upload(*paths) ⇒ Object

Transfer files to a machine via Net::SCP.

  • paths is an Array of files to upload. The last element is the

directory to upload to. If uploading a single file, the last element can be a file path. The list of files can also include StringIO objects. The target directory will be created if it does not exist, but only when multiple files are being transferred. This method will fail early if there are obvious problems with the input parameters. An exception is raised and no files are transferred. Always return nil.

NOTE: Changes to current working directory with cd or [] are ignored.



148
# File 'lib/rye/cmd.rb', line 148

def file_upload(*paths); net_scp_transfer!(:upload, false, *paths); end

#file_verified?(path, expected_digest, digest_type = :md5) ⇒ Boolean

Does the calculated digest of path match the known expected_digest? This is useful for verifying downloaded files. digest_type must be one of: :md5, :sha1, :sha2

Returns:

  • (Boolean)


288
289
290
291
292
293
294
# File 'lib/rye/cmd.rb', line 288

def file_verified?(path, expected_digest, digest_type=:md5)
  return false unless file_exists?(path)
  raise "Unknown disgest type: #{digest_type}" unless can?("digest_#{digest_type}")
  digest = self.send("digest_#{digest_type}", path).first
  info "#{digest_type} (#{path}) = #{digest}"
  digest.to_s == expected_digest.to_s
end

#file_write(filepath, newcontent, backup = false) ⇒ Object

Write newcontent to remote filepath. If the file exists it will be overwritten. If backup is specified, filepath will be copied to filepath-previous before appending.



225
226
227
228
229
230
231
232
233
# File 'lib/rye/cmd.rb', line 225

def file_write(filepath, newcontent, backup=false)
  if self.file_exists?(filepath)
    self.cp filepath, "#{filepath}-previous" if backup
  end
  
  content = StringIO.new
  content.puts newcontent
  self.file_upload content, filepath
end

#getconf(*args) ⇒ Object



119
# File 'lib/rye/cmd.rb', line 119

def getconf(*args) run_command('getconf', args) end

#git(*args) ⇒ Object



72
# File 'lib/rye/cmd.rb', line 72

def git(*args) run_command('git', args) end

#grep(*args) ⇒ Object



81
# File 'lib/rye/cmd.rb', line 81

def grep(*args) run_command('grep', args) end

#gunzip(*args) ⇒ Object



114
# File 'lib/rye/cmd.rb', line 114

def gunzip(*args) run_command('gunzip', args) end

#gzip(*args) ⇒ Object



89
# File 'lib/rye/cmd.rb', line 89

def gzip(*args) run_command('gzip', args) end

#hg(*args) ⇒ Object



64
# File 'lib/rye/cmd.rb', line 64

def hg(*args) run_command('hg', args) end

#history(*args) ⇒ Object



120
# File 'lib/rye/cmd.rb', line 120

def history(*args) run_command('history', args) end

#hostname(*args) ⇒ Object



125
# File 'lib/rye/cmd.rb', line 125

def hostname(*args) run_command('hostname', args) end

#irb(*args, &blk) ⇒ Object

When called without a block this will open an interactive shell session.



40
41
42
# File 'lib/rye/cmd.rb', line 40

def irb(*args, &blk)
    __shell 'irb', *args, &blk
end

#ldconfig(*args) ⇒ Object



126
# File 'lib/rye/cmd.rb', line 126

def ldconfig(*args) run_command('ldconfig', args) end

#ln(*args) ⇒ Object



62
# File 'lib/rye/cmd.rb', line 62

def ln(*args) run_command('ln', args) end

#ls(*args) ⇒ Object



57
# File 'lib/rye/cmd.rb', line 57

def ls(*args) run_command('ls', args) end

#make(*args) ⇒ Object



90
# File 'lib/rye/cmd.rb', line 90

def make(*args) run_command('make', args) end

#mkdir(*args) ⇒ Object



99
# File 'lib/rye/cmd.rb', line 99

def mkdir(*args) run_command('mkdir', args) end

#mkfs(*args) ⇒ Object



88
# File 'lib/rye/cmd.rb', line 88

def mkfs(*args) run_command('mkfs', args) end

#mount(*args) ⇒ Object



97
# File 'lib/rye/cmd.rb', line 97

def mount(*args) run_command("mount", args) end

#mv(*args) ⇒ Object



56
# File 'lib/rye/cmd.rb', line 56

def mv(*args) run_command("mv", args) end

#perl(*args) ⇒ Object



84
# File 'lib/rye/cmd.rb', line 84

def perl(*args) run_command('perl', args) end

#printenv(*args) ⇒ Object



124
# File 'lib/rye/cmd.rb', line 124

def printenv(*args) run_command('printenv', args) end

#ps(*args) ⇒ Object



58
# File 'lib/rye/cmd.rb', line 58

def ps(*args) run_command('ps', args) end

#pwd(*args) ⇒ Object



69
# File 'lib/rye/cmd.rb', line 69

def pwd(*args) run_command('pwd', args) end

#python(*args) ⇒ Object



113
# File 'lib/rye/cmd.rb', line 113

def python(*args) run_command('python', args) end

#rake(*args) ⇒ Object

def kill(*args) run_command(‘kill’, args) end



80
# File 'lib/rye/cmd.rb', line 80

def rake(*args) run_command('rake', args) end

#ruby(*args) ⇒ Object



85
# File 'lib/rye/cmd.rb', line 85

def ruby(*args) run_command('ruby', args) end

#rudy(*args) ⇒ Object



83
# File 'lib/rye/cmd.rb', line 83

def rudy(*args) run_command('rudy', args) end

#rudy_ec2(*args) ⇒ Object



127
# File 'lib/rye/cmd.rb', line 127

def rudy_ec2(*args) run_command('rudy-ec2', args) end

#rudy_s3(*args) ⇒ Object



121
# File 'lib/rye/cmd.rb', line 121

def rudy_s3(*args) run_command('rudy-s3', args) end

#rudy_sdb(*args) ⇒ Object



128
# File 'lib/rye/cmd.rb', line 128

def rudy_sdb(*args) run_command('rudy-sdb', args) end

#rye(*args) ⇒ Object



68
# File 'lib/rye/cmd.rb', line 68

def rye(*args) run_command('rye', args) end

#sed(*args) ⇒ Object



73
# File 'lib/rye/cmd.rb', line 73

def sed(*args) run_command('sed', args) end

#sh(*args, &blk) ⇒ Object

When called without a block this will open an interactive shell session.



46
47
48
49
# File 'lib/rye/cmd.rb', line 46

def sh(*args, &blk)
  setenv('PS1', "(rye) $\ ")
  __shell 'sh', *args, &blk
end

#siege(*args) ⇒ Object



107
# File 'lib/rye/cmd.rb', line 107

def siege(*args) run_command("siege", args) end

#sleep(*args) ⇒ Object



98
# File 'lib/rye/cmd.rb', line 98

def sleep(*args) run_command("sleep", args) end

#stella(*args) ⇒ Object



109
# File 'lib/rye/cmd.rb', line 109

def stella(*args) run_command("stella", args) end

#string_append(filepath, newcontent, backup = false) ⇒ Object

Shorthand for file_append(‘remote/path’, StringIO.new(‘file content’))

Appends the content of the String str to remote_path. Returns nil



194
195
196
# File 'lib/rye/cmd.rb', line 194

def string_append(filepath, newcontent, backup=false)
  file_append(remote_path, StringIO.new(str), backup)
end

#string_download(*paths) ⇒ Object Also known as: str_download

Shorthand for file_download(‘remote/path’).string

Returns a String containing the content of all remote paths.



178
179
180
# File 'lib/rye/cmd.rb', line 178

def string_download(*paths)
  net_scp_transfer!(:download, false, *paths).string
end

#string_upload(str, remote_path) ⇒ Object Also known as: str_upload

Shorthand for file_upload(StringIO.new(‘file content’), ‘remote/path’)

Uploads the content of the String str to remote_path. Returns nil



186
187
188
# File 'lib/rye/cmd.rb', line 186

def string_upload(str, remote_path)
  net_scp_transfer!(:upload, false, StringIO.new(str), remote_path)
end

#su(*args) ⇒ Object



61
# File 'lib/rye/cmd.rb', line 61

def su(*args) run_command('su', args) end

#svn(*args) ⇒ Object



70
# File 'lib/rye/cmd.rb', line 70

def svn(*args) run_command('svn', args) end

#tail(*args) ⇒ Object



94
# File 'lib/rye/cmd.rb', line 94

def tail(*args) run_command('tail', args) end

#tar(*args) ⇒ Object



76
# File 'lib/rye/cmd.rb', line 76

def tar(*args) run_command('tar', args) end

#template_upload(*paths) ⇒ Object

Parse a template and upload that as a file to remote_path.



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/rye/cmd.rb', line 241

def template_upload(*paths)
  remote_path = paths.pop
  templates = []
  paths.collect! do |path|      
    if StringIO === path
      path.rewind
      template = Rye::Tpl.new(path.read, "inline-template")
    elsif String === path
      raise "No such file: #{Dir.pwd}/#{path}" unless File.exists?(path)
      template = Rye::Tpl.new(File.read(path), File.basename(path))
    end
    template.result!(binding)
    templates << template
    template.path
  end
  paths << remote_path
  ret = self.file_upload *paths
  templates.each { |template| 
    tmp_path = File.join(remote_path, File.basename(template.path))
    if file_exists?(tmp_path)
      mv tmp_path, File.join(remote_path, template.basename)
    end
    template.delete 
  }
  ret
end

#template_write(filepath, template) ⇒ Object



236
237
238
# File 'lib/rye/cmd.rb', line 236

def template_write(filepath, template)
  template_upload template, filepath
end

#test(*args) ⇒ Object



87
# File 'lib/rye/cmd.rb', line 87

def test(*args) run_command('test', args) end

#touch(*args) ⇒ Object



100
# File 'lib/rye/cmd.rb', line 100

def touch(*args) run_command('touch', args) end

#try(*args) ⇒ Object



77
# File 'lib/rye/cmd.rb', line 77

def try(*args) run_command('tar', args) end

#umount(*args) ⇒ Object



110
# File 'lib/rye/cmd.rb', line 110

def umount(*args) run_command("umount", args) end

#uname(*args) ⇒ Object



101
# File 'lib/rye/cmd.rb', line 101

def uname(*args) run_command('uname', args) end

#unxz(*args) ⇒ Object



95
# File 'lib/rye/cmd.rb', line 95

def unxz(*args) run_command('unxz', args) end

#unzip(*args) ⇒ Object



104
# File 'lib/rye/cmd.rb', line 104

def unzip(*args) run_command('unzip', args) end

#uptime(*args) ⇒ Object



112
# File 'lib/rye/cmd.rb', line 112

def uptime(*args) run_command("uptime", args) end

#useradd(*args) ⇒ Object



117
# File 'lib/rye/cmd.rb', line 117

def useradd(*args) run_command('useradd', args) end

#wc(*args) ⇒ Object

NOTE: See Rye::Box for the implementation of cd def cd(*args) run_command(‘cd’, args) end def rm(*args) run_command(‘rm’, args) end



54
# File 'lib/rye/cmd.rb', line 54

def wc(*args) run_command('wc', args) end

#wget(*args) ⇒ Object



91
# File 'lib/rye/cmd.rb', line 91

def wget(*args) run_command('wget', args) end

#which(*args) ⇒ Object



106
# File 'lib/rye/cmd.rb', line 106

def which(*args) run_command('which', args) end

#whoami(*args) ⇒ Object



115
# File 'lib/rye/cmd.rb', line 115

def whoami(*args) run_command('whoami', args) end

#xz(*args) ⇒ Object



65
# File 'lib/rye/cmd.rb', line 65

def xz(*args) run_command('xz', args) end