Class | AutomateIt::AccountManager::PasswdPTY |
In: |
lib/automateit/account_manager/passwd_pty.rb
|
Parent: | ::AutomateIt::AccountManager::BaseDriver |
An AccountManager driver for passwd command found on Unix-like systems using the Ruby PTY implementation.
WARNING: The Ruby PTY module is unreliable or unavailable on most platforms. It may hang indefinitely or report incorrect results. Every attempt has been made to work around these problems, but this is a low-level problem. You are strongly encouraged to install the expect program, which works flawlessly. Once the expect program is installed, passwords will be changed using the AccountManager::PasswdExpect driver, which works properly.
# File lib/automateit/account_manager/passwd_pty.rb, line 25 def passwd(user, password, opts={}) log.info(PERROR+"Setting password with flaky Ruby PTY, which hangs or fails randomly. Install 'expect' (http://expect.nist.gov/) for reliable operation.") _passwd_helper(user, password, opts) do log.silence(Logger::WARN) do interpreter.mktemp do |filename| tries = 5 exitstatus = nil begin exitstruct = _passwd_raw(user, password, opts) if exitstatus and not exitstruct.exitstatus.zero? # FIXME AccountManager::Linux#passwd -- The `passwd` command randomly returns exit status 10 even when it succeeds. What does this mean and how to deal with it?! Temporary workaround is to throw an error and force a retry. raise Errno::EPIPE.new("bad exitstatus %s" % exitstruct.exitstatus) end rescue Errno::EPIPE => e # FIXME AccountManager::Linux#passwd -- EPIPE exception randomly thrown even when `passwd` succeeds. How to eliminate it? How to differentiate between this false error and a real one? if tries <= 0 raise e else tries -= 1 retry end end return exitstruct.exitstatus.zero? end end end end
# File lib/automateit/account_manager/passwd_pty.rb, line 54 def _passwd_raw(user, password, opts={}) quiet = (opts[:quiet] or not log.info?) require 'open4' return Open4::popen4("passwd %s 2>&1" % user) do |pid, sin, sout, serr| $expect_verbose = ! quiet 2.times do sout.expect(/:/) sleep 0.1 # Reduce chance of passwd thinking we're a robot :( sin.puts password puts "*" * 12 unless quiet end end end