Class: DO::Server

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/do/server.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#ask, #wait, #yes?

Constructor Details

#initialize(name, host, user, options = {}) ⇒ Server

Initialize a new DO Server

name

is a shortcut useful in rake tasks

host

is the host where we connect

user

the user of our server

options

an hash of options used by ssh/sftpd, where normally we provide :keys => [‘path/to/key.pem’]

Examples:

srv1 = DO::Server.new(:srv1, 'srv1.lipsiasoft.biz', 'root', :keys => %w[/path/to/key.pem]


21
22
23
# File 'lib/do/server.rb', line 21

def initialize(name, host, user, options={})
 @name, @host, @user, @options = name, host, user, options
end

Instance Attribute Details

#hostObject (readonly)

Returns the value of attribute host.



8
9
10
# File 'lib/do/server.rb', line 8

def host
  @host
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/do/server.rb', line 8

def name
  @name
end

#optionsObject (readonly)

Returns the value of attribute options.



8
9
10
# File 'lib/do/server.rb', line 8

def options
  @options
end

#userObject (readonly)

Returns the value of attribute user.



8
9
10
# File 'lib/do/server.rb', line 8

def user
  @user
end

Instance Method Details

#append(pattern, file, where = :bottom) ⇒ Object

Append text into a given file in a specified location

Locations can be:

:top, :start

Add your text before the old content

:bottom, :end

Append your text at bottom of your file

Examples:

append "By default Im at bottom", "/tmp/file"
append "Im on top", "/tmp/file", :top


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

def append(pattern, file, where=:bottom)
  was = sftp.file.open(file, "r") { |f| f.read }

  if was.include?(pattern)
    log "'%s' already match your pattern" % file
    return false
  else
    replacement = case where
      when :top, :start  then pattern+was
      when :bottom, :end then was+pattern
      else raise "%s is not a valid, available values are (:top, :start, :bottom, :end)" % where.inspect
    end
  end

  log "append to '%s' in '%s'" % [where, file]
  sftp.file.open(file, "w") { |f| f.write(replacement) }
end

#closeObject

Method used to close the ssh connection



58
59
60
# File 'lib/do/server.rb', line 58

def close
  ssh.close if @_ssh
end

#download(from, to, options = {}) ⇒ Object Also known as: get

Download a file o a directory from a remote location to a local location As for upload we can download an entire directory providing

:recursive => true

Examples

download(/tmp/file, /my/file)
get(/tmp/dir, /my, :recursive => true)


144
145
146
147
# File 'lib/do/server.rb', line 144

def download(from, to, options={})
  log "download from '%s' to '%s'" % [from, to]
  sftp.download!(from, to)
end

#exist?(file) ⇒ Boolean

Returns true if a given file exist on the remote server

Returns:

  • (Boolean)


107
108
109
# File 'lib/do/server.rb', line 107

def exist?(file)
  run("test -e #{file} && echo True", :silent => true) == "True"
end

#log(text = "", new_line = true) ⇒ Object

Method used to print a formatted version of our commands using DO::Server::DO_LOGGER_FORMAT, by default we have a nice colored version like:

srv1@root ~ # ls -al

If you don’t like colors or our format feel free to edit:

Examples:

DO::Server::DO_LOGGER_FORMAT = "%s@%s$ %s"


37
38
39
# File 'lib/do/server.rb', line 37

def log(text="", new_line=true)
  super(DO_LOGGER_FORMAT % [user, name, text], new_line)
end

#read(file) ⇒ Object

Return the content of a given file



114
115
116
# File 'lib/do/server.rb', line 114

def read(file)
  run("cat #{file}", :silent => true)
end

#replace(pattern, replacement, file) ⇒ Object Also known as: gsub

Replace a pattern with text in a given file.

Pattern can be:

  • string

  • regexp

  • symbol (:all, :any, :everything) => replace all content

Examples

replace :all, my_template, "/root/.gemrc"
replace /^motd/, "New motd", "/etc/motd"
replace "Old motd, "New motd", "/etc/motd"


164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/do/server.rb', line 164

def replace(pattern, replacement, file)
  was = sftp.file.open(file, "r") { |f| f.read }
  found = case pattern
    when :all, :any, :everything
      log "replace \e[1m%s\e[0m in '%s'" % [pattern, file]
      true
    when Regexp
      log "replace \e[1m%s\e[0m in '%s'" % [pattern.inspect, file]
      replacement = was.gsub(pattern, replacement)
      was =~ pattern
    when String
      log "replace \e[1m%s\e[0m in '%s'" % ["String", file]
      replacement = was.gsub(pattern, replacement)
      was.include?(pattern)
    else raise "%s is not a valid. You can use a String, Regexp or :all, :any and :everything" % pattern.inspect
  end

  if found
    sftp.file.open(file, "w") { |f| f.write replacement }
  else
    log "\e[31m '%s' does not include your \e[1mpattern\e[0m" % file unless was =~ pattern
  end
end

#run(*args) ⇒ Object

Run commands on remote server

Examples:

run 'ls -al'
run 'ls', '-al'
run 'mysqladmin -u root -p password 'new', :input => 'oldpassword'


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/do/server.rb', line 70

def run(*args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  cmd = args.join(" ")
  if options[:as]
    if options[:as] == 'root'
      cmd = "sudo #{cmd.gsub(/'/, "\'")}"
    else
      cmd = "su #{options[:as]} -c '#{cmd.gsub(/'/, "\'")}'"
    end
  end
  log cmd
  result = ""
  ssh.open_channel do |channel|
    channel.request_pty do |c, success|
      raise "could not request pty" unless success
      channel.exec cmd
      channel.on_data do |c_, data|
        result << data
        DO_LOGGER.print(data) unless options[:silent]
        if options[:input]
          match = options[:match] || /password/i
          if data =~ match
            options[:input] += "\n" if options[:input][-1] != ?\n
            channel.send_data(options[:input])
            DO_LOGGER.puts(options[:input]) unless options[:silent] || data =~ /password/i
          end
        end
      end
    end
  end
  ssh.loop
  result.chomp
end

#sftpObject

The sftp connection used to perform uploads, downloads



51
52
53
# File 'lib/do/server.rb', line 51

def sftp
  @_sftp ||= Net::SFTP.start(host, user, options)
end

#sshObject

This is the ssh connection



44
45
46
# File 'lib/do/server.rb', line 44

def ssh
  @_ssh ||= Net::SSH.start(host, user, options)
end

#upload(from, to, options = {}) ⇒ Object Also known as: up

Upload a file or directory from a local location to the remote location When you need to upload a directory you need to provide:

:recursive => true

Examples

upload(/my/file, /tmp/file)
up(/my/dir, /tmp, :recursive => true)


128
129
130
131
# File 'lib/do/server.rb', line 128

def upload(from, to, options={})
  log "upload from '%s' to '%s'" % [from, to]
  sftp.upload!(from, to)
end