Class: Docker::Swarm::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/docker/swarm/node.rb

Overview

This class represents a Docker Swarm Node.

Constant Summary collapse

AVAILABILITY =
{
  active: "active",
  drain:  "drain"
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(swarm, hash) ⇒ Node

Returns a new instance of Node.



9
10
11
12
# File 'lib/docker/swarm/node.rb', line 9

def initialize(swarm, hash)
  @hash = hash
  @swarm = swarm
end

Instance Attribute Details

#hashObject (readonly)

Returns the value of attribute hash.



3
4
5
# File 'lib/docker/swarm/node.rb', line 3

def hash
  @hash
end

#swarmObject (readonly)

Returns the value of attribute swarm.



3
4
5
# File 'lib/docker/swarm/node.rb', line 3

def swarm
  @swarm
end

Class Method Details

.networks_on_host(connection, swarm) ⇒ Object



180
181
182
183
184
185
186
187
188
# File 'lib/docker/swarm/node.rb', line 180

def self.networks_on_host(connection, swarm)
  networks = []
  response = connection.get("/networks", {}, full_response: true, expects: [200])
  network_hashes = JSON.parse(response.body)
  network_hashes.each do |network_hash|
    networks << Docker::Swarm::Network.new(swarm, network_hash)
  end
  return networks
end

.remove(node_id, connection) ⇒ Object



172
173
174
175
176
177
178
# File 'lib/docker/swarm/node.rb', line 172

def self.remove(node_id, connection)
  query = {}
  response = connection.delete("/nodes/#{node_id}", query, expects: [200, 406, 500], full_response: true)
  if (response.status != 200)
    raise "Error deleting node: HTTP-#{response.status} #{response.body}"
  end
end

Instance Method Details

#activateObject



83
84
85
# File 'lib/docker/swarm/node.rb', line 83

def activate
  change_availability(:active)
end

#availabilityObject



46
47
48
# File 'lib/docker/swarm/node.rb', line 46

def availability
  return @hash['Spec']['Availability'].to_sym
end

#change_availability(new_availability) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/docker/swarm/node.rb', line 131

def change_availability(new_availability)
  raise "Bad availability param: #{availability}" if (!AVAILABILITY[availability])
  refresh
  if (self.availability != new_availability)
    @hash['Spec']['Availability'] = AVAILABILITY[new_availability]
    query = {version: @hash['Version']['Index']}
    response = @swarm.connection.post("/nodes/#{self.id}/update", query, :body => @hash['Spec'].to_json, expects: [200, 500], full_response: true)
    if (response.status != 200)
      raise "Error changing node availability: #{response.body} HTTP-#{response.status}"
    end
  end
end

#connectionObject



28
29
30
31
32
33
34
# File 'lib/docker/swarm/node.rb', line 28

def connection
  if (@swarm) && (@swarm.node_hash[id()])
    return @swarm.node_hash[id()][:connection]
  else
    return nil
  end
end

#drain(opts = {}) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'lib/docker/swarm/node.rb', line 54

def drain(opts = {})
  change_availability(:drain)
  if (opts[:wait_for_drain])
    opts[:wait_seconds]
    while (running_tasks.length > 0)
      puts "Waiting for node (#{host_name}) to drain.  Still has #{running_tasks.length} tasks running."
    end
  end
end

#find_network_by_id(network_id) ⇒ Object



162
163
164
165
166
167
168
169
# File 'lib/docker/swarm/node.rb', line 162

def find_network_by_id(network_id)
  networks.each do |network|
    if (network.id == network_id)
      return network
    end
  end
  return nil
end

#find_network_by_name(network_name) ⇒ Object



153
154
155
156
157
158
159
160
# File 'lib/docker/swarm/node.rb', line 153

def find_network_by_name(network_name)
  networks.each do |network|
    if (network.name == network_name)
      return network
    end
  end
  return nil
end

#host_nameObject



24
25
26
# File 'lib/docker/swarm/node.rb', line 24

def host_name
  return @hash['Description']['Hostname']
end

#idObject



20
21
22
# File 'lib/docker/swarm/node.rb', line 20

def id 
  return @hash['ID']
end

#leave(force = true) ⇒ Object



125
126
127
128
129
# File 'lib/docker/swarm/node.rb', line 125

def leave(force = true)
  drain(wait_for_drain: true, wait_seconds: 60)
  # change_availability(:active)
  @swarm.leave(self, force)
end

#networksObject



144
145
146
147
148
149
150
151
# File 'lib/docker/swarm/node.rb', line 144

def networks()
  if (connection)
    return Docker::Swarm::Node.networks_on_host(connection, @swarm)
  else
    debugger
    raise "No connection set for node: #{self.host_name}, ID: #{self.id}"
  end
end

#refreshObject



14
15
16
17
18
# File 'lib/docker/swarm/node.rb', line 14

def refresh
  query = {}
  response = @swarm.connection.get("/nodes/#{id}", query, expects: [200])
  @hash = JSON.parse(response)
end

#removeObject



87
88
89
90
91
92
93
94
95
96
# File 'lib/docker/swarm/node.rb', line 87

def remove
  leave(true)
  refresh
  start_time = Time.now
  while (self.status != 'down')
    refresh
    raise "Node not down 60 seconds after leaving swarm: #{self.host_name}" if (Time.now.to_i - start_time.to_i > 60)
  end
  Docker::Swarm::Node.remove(self.id, @swarm.connection)
end

#remove_network(network) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/docker/swarm/node.rb', line 104

def remove_network(network)
  attempts = 0
  if (self.connection == nil)
    puts "Warning:  node asked to remove network, but no connection for node: #{self.id} #{self.host_name}"
  else
    while (self.find_network_by_id(network.id) != nil)
      response = self.connection.delete("/networks/#{network.id}", {}, expects: [204, 404, 500], full_response: true)
      if (response.status == 500)
        puts "Warning:  Deleting network (#{network.name}) from #{self.host_name} returned HTTP-#{response.status}  #{response.body}"
      end

      sleep 1
      attempts += 1
      if (attempts > 30)
        raise "Failed to remove network: #{network.name} from #{self.host_name}, operation timed out. Response: HTTP#{response.status}  #{response.body}"
      end
    end
  end
end

#remove_network_with_name(network_name) ⇒ Object



99
100
101
102
# File 'lib/docker/swarm/node.rb', line 99

def remove_network_with_name(network_name)
  network = find_network_by_name(network_name)
  self.remove_network(network) if (network)
end

#roleObject



36
37
38
39
40
41
42
43
44
# File 'lib/docker/swarm/node.rb', line 36

def role
  if (@hash['Spec']['Role'] == "worker")
    return :worker
  elsif (@hash['Spec']['Role'] == "manager")
    return :manager
  else
    raise "Couldn't determine machine role from spec: #{@hash['Spec']}"
  end
end

#running_tasksObject



73
74
75
# File 'lib/docker/swarm/node.rb', line 73

def running_tasks
  return tasks.select {|t| t.status == 'running'}
end

#statusObject



50
51
52
# File 'lib/docker/swarm/node.rb', line 50

def status
  return @hash['Status']['State']
end

#swarm_connectionObject



64
65
66
67
68
69
70
# File 'lib/docker/swarm/node.rb', line 64

def swarm_connection
  node_hash = @swarm.node_hash[self.id]
  if (node_hash)
    return node_hash[:connection]
  end
  return nil
end

#tasksObject



77
78
79
80
81
# File 'lib/docker/swarm/node.rb', line 77

def tasks
  return @swarm.tasks.select {|t| 
    (t.node != nil) && (t.node.id == self.id)
  }
end