class LockManager::Worker

Attributes

connection[R]
host[R]
user[R]

Public Class Methods

new(connection, host) click to toggle source
# File lib/lock_manager/worker.rb, line 7
def initialize(connection, host)
  @connection = connection
  if host =~ Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
    raise ArgumentError, 'Please use a DNS name rather than an IP address.'
  else
    # Using the shortname of the host has the downside of being unable to
    # lock two hosts with the same shortname and different domains.
    # However, since the majority of users interact with shortname only,
    # we're using shortname to normalize and prevent the system from
    # allowing a lock on aixbuilder1 if aixbuilder1.delivery.puppetlabs.net
    # is locked.
    @host = host.split('.')[0]
  end
end

Public Instance Methods

lock(user, reason = nil) click to toggle source
# File lib/lock_manager/worker.rb, line 22
def lock(user, reason = nil)
  lock_contents = {
    user:  user,
    time: Time.now.to_s,
    reason: reason
  }
  r = connection.write_if_not_exists host, lock_contents.to_json
  log "#{host} already locked." if r == false
  r
end
lock!(user, reason = nil) click to toggle source
# File lib/lock_manager/worker.rb, line 33
def lock!(user, reason = nil)
  lock_contents = {
    user:  user,
    time: Time.now.to_s,
    reason: reason
  }
  r = connection.write host, lock_contents.to_json
  r == 'OK'
end
lock_user() click to toggle source
# File lib/lock_manager/worker.rb, line 66
def lock_user
  lock_data = connection.read host
  return false unless lock_data
  result = JSON.parse lock_data
  result['user']
end
locked?() click to toggle source

Boolean to figure out if a host is locked.

@return [Bool] whether or not the host is locked.

# File lib/lock_manager/worker.rb, line 46
def locked?
  !!connection.read(host)
end
log(message) click to toggle source
# File lib/lock_manager/worker.rb, line 92
def log(message)
  warn message
end
polling_lock(user, reason = nil, max_sleep = 600) click to toggle source
# File lib/lock_manager/worker.rb, line 73
def polling_lock(user, reason = nil, max_sleep = 600)
  sleep_duration = 1
  return lock(user, reason) unless locked?
  loop do
    log "#{host} is locked..."
    log "waiting #{sleep_duration} seconds."
    sleep sleep_duration
    sleep_duration *= 2
    sleep_duration = max_sleep if sleep_duration > max_sleep
    break unless locked?
  end
  lock(user, reason)
end
show() click to toggle source
# File lib/lock_manager/worker.rb, line 87
def show
  data = connection.read(host)
  data ? JSON.parse(data) : nil
end
unlock(user) click to toggle source
# File lib/lock_manager/worker.rb, line 50
def unlock(user)
  if !locked?
    log "Refusing to unlock. No lock exists on #{host}."
    false
  elsif user == lock_user
    unlock!
  else
    log "Refusing to unlock. Lock on #{host} is owned by #{lock_user}."
    false
  end
end
unlock!() click to toggle source
# File lib/lock_manager/worker.rb, line 62
def unlock!
  connection.remove(host) > 0
end