Class: PicsolveDockerBuilder::Helpers::KubernetesManager

Inherits:
Object
  • Object
show all
Includes:
Base
Defined in:
lib/picsolve_docker_builder/helpers/kubernetes_manager.rb

Overview

Ruby representation of a kuberentes cluster

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Base

#base_dir, #config, #config_file, #config_path, #config_paths, #create_logger, #default_config, #log, #read_config, #validate_config

Constructor Details

#initialize(composer, host, type = nil, port = nil) ⇒ KubernetesManager

Returns a new instance of KubernetesManager.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 16

def initialize(composer, host, type = nil, port = nil)
  # default type is http
  type ||= :http

  if type == :ssh_forward
    @type = type
    @port = port || 22
  end

  if type == :http
    @type = type
    @port = port || 8080
  end

  @host = host
  @composer = composer
end

Instance Attribute Details

#hostObject (readonly)

Returns the value of attribute host.



14
15
16
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 14

def host
  @host
end

#portObject (readonly)

Returns the value of attribute port.



14
15
16
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 14

def port
  @port
end

#typeObject (readonly)

Returns the value of attribute type.



14
15
16
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 14

def type
  @type
end

Instance Method Details

#app_nameObject



120
121
122
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 120

def app_name
  @composer.app_name
end

#cleanupObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 38

def cleanup
  stages_allowed = %w(ci test)
  unless stages_allowed.include? stage
    log.error "Refuse to cleanup in stage #{stage}." \
      "I only clean up in stages #{stages_allowed.join ', '}"
    exit 1
  end
  rcs = []
  pg_requirements = []

  # find pg databases
  images.each do |i|
    i.requirements(self).each do |requirement|
      continue unless requirement.is_a?(
        PicsolveDockerBuilder::Composer::Requirements::Postgres
      )
      pg_requirements.append(requirement)
    end
    rcs += i.rc(self).existing_rcs
  end

  log.info "Cleanup replication controllers for '#{app_name}' " \
  "in '#{stage}'"
  rcs.each do |rc|
    rc.remove
    rc.remove_pods_orphan
  end

  sleep 2

  log.info "Cleanup databases for '#{app_name}' in '#{stage}'"
  pg_requirements.each do |pg|
    pg.cleanup_postgres_database
  end
end

#clientObject



112
113
114
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 112

def client
  @client ||= create_client
end

#create_clientObject



74
75
76
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 74

def create_client
  Kubeclient::Client.new kubernetes_url, 'v1'
end

#deployObject



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 174

def deploy
  log.info "start deploying app_name=#{app_name} to stage #{stage}"

  # reset hash
  @hash = nil

  deploy_services

  deploy_rcs

  successful_images, unready_images = wait_for_deployed_rcs

  remove_old_rcs(successful_images)

  fail "Failed to deploy this service: #{unready_images.map(&:name)}" \
    if unready_images.length > 0
end

#deploy_rcsObject



198
199
200
201
202
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 198

def deploy_rcs
  images.each do |i|
    i.rc(self).deploy
  end
end

#deploy_servicesObject



192
193
194
195
196
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 192

def deploy_services
  images.each do |i|
    i.service(self).deploy
  end
end

#imagesObject



116
117
118
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 116

def images
  @composer.images
end

#kubernetes_urlObject



78
79
80
81
82
83
84
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 78

def kubernetes_url
  if type == :ssh_forward
    kubernetes_url_ssh_forward
  elsif type == :http
    kubernetes_url_http
  end
end

#kubernetes_url_httpObject



86
87
88
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 86

def kubernetes_url_http
  "http://#{host}:#{port}"
end

#kubernetes_url_ssh_forwardObject



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 99

def kubernetes_url_ssh_forward
  @ssh = SshConnection.new(
    ssh_host: host,
    ssh_port: port
  )
  forward = @ssh.forward('127.0.0.1', 8080, 10_000)
  @ssh.start
  at_exit do
    kubernetes_url_ssh_forward_stop
  end
  "http://127.0.0.1:#{forward.local_port}"
end

#kubernetes_url_ssh_forward_stopObject



90
91
92
93
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 90

def kubernetes_url_ssh_forward_stop
  @ssh.stop unless @ssh_forward.nil?
  @ssh = nil
end

#rc(image) ⇒ Object



132
133
134
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 132

def rc(image)
  Kubernetes::Rc.new(image, self)
end

#remove_old_rcs(successful_images) ⇒ Object



164
165
166
167
168
169
170
171
172
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 164

def remove_old_rcs(successful_images)
  # build list of successful deplyoed images
  successful_images.each do |i|
    log.debug "Remove old pods for #{i.name}"
    i.rc(self).remove_old_rcs
    log.debug "Remove orphaned pods for #{i.name}"
    i.rc(self).remove_pods_orphan
  end
end

#service(image) ⇒ Object



128
129
130
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 128

def service(image)
  Kubernetes::Service.new(image, self)
end

#stageObject



124
125
126
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 124

def stage
  @composer.stage
end

#stopObject



95
96
97
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 95

def stop
  kubernetes_url_ssh_forward_stop if type == :ssh_forward
end

#template_labels(i) ⇒ Object



210
211
212
213
214
215
216
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 210

def template_labels(i)
  {
    'name' => i.name,
    'app_name' => i.composer.app_name,
    'stage' => i.composer.stage
  }
end

#template_labels_pods(i) ⇒ Object



204
205
206
207
208
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 204

def template_labels_pods(i)
  c = template_labels(i)
  c['deployment'] = i.composer.hash
  c
end

#userObject



34
35
36
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 34

def user
  'core'
end

#wait_for_deployed_rcsObject



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 136

def wait_for_deployed_rcs
  wait_timeout = 300
  wait_sleep = 2
  wait_beginning = 15
  wait_count = wait_beginning
  unready_images = images.dup
  log.info \
    'Wait for the new pods to be up and running for at least 20 seconds'
  sleep wait_beginning
  loop do
    unready_images.each do |i|
      unready_images.delete(i) if i.rc(self).ready?
    end
    log.debug "Still waiting for: #{unready_images.map(&:name)}"
    $stdout.flush
    $stderr.flush
    wait_count += wait_sleep
    break if wait_count > wait_timeout
    break if unready_images.length == 0
    sleep wait_sleep
  end
  successful_images = images.dup
  unready_images.each do |u|
    successful_images.delete(u)
  end
  [successful_images, unready_images]
end