Class: LockManager::Worker

Inherits:
Object
  • Object
show all
Defined in:
lib/lock_manager/worker.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, host) ⇒ Worker

Returns a new instance of Worker.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



5
6
7
# File 'lib/lock_manager/worker.rb', line 5

def connection
  @connection
end

#hostObject (readonly)

Returns the value of attribute host.



5
6
7
# File 'lib/lock_manager/worker.rb', line 5

def host
  @host
end

#userObject (readonly)

Returns the value of attribute user.



5
6
7
# File 'lib/lock_manager/worker.rb', line 5

def user
  @user
end

Instance Method Details

#lock(user, reason = nil) ⇒ Object



22
23
24
25
26
27
28
29
30
31
# 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) ⇒ Object



33
34
35
36
37
38
39
40
41
# 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_userObject



66
67
68
69
70
71
# 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?Bool

Boolean to figure out if a host is locked.

Returns:

  • (Bool)

    whether or not the host is locked.



46
47
48
# File 'lib/lock_manager/worker.rb', line 46

def locked?
  !!connection.read(host)
end

#log(message) ⇒ Object



92
93
94
# File 'lib/lock_manager/worker.rb', line 92

def log(message)
  warn message
end

#polling_lock(user, reason = nil, max_sleep = 600) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
# 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

#showObject



87
88
89
90
# File 'lib/lock_manager/worker.rb', line 87

def show
  data = connection.read(host)
  data ? JSON.parse(data) : nil
end

#unlock(user) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
# 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!Object



62
63
64
# File 'lib/lock_manager/worker.rb', line 62

def unlock!
  connection.remove(host) > 0
end