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



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

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
# 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
  log.info "Cleanup databases for '#{app_name}' in '#{stage}'"
  rcs = []
  images.each do |i|
    i.requirements(self).each do |requirements|
      continue unless  requirements.is_a?(
        PicsolveDockerBuilder::Composer::Requirements::Postgres
      )
      requirements.cleanup_postgres_database
    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
end

#clientObject



103
104
105
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 103

def client
  @client ||= create_client
end

#create_clientObject



65
66
67
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 65

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

#deployObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 165

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



189
190
191
192
193
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 189

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

#deploy_servicesObject



183
184
185
186
187
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 183

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

#imagesObject



107
108
109
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 107

def images
  @composer.images
end

#kubernetes_urlObject



69
70
71
72
73
74
75
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 69

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

#kubernetes_url_httpObject



77
78
79
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 77

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

#kubernetes_url_ssh_forwardObject



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 90

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



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

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

#rc(image) ⇒ Object



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

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

#remove_old_rcs(successful_images) ⇒ Object



155
156
157
158
159
160
161
162
163
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 155

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



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

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

#stageObject



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

def stage
  @composer.stage
end

#stopObject



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

def stop
  kubernetes_url_ssh_forward_stop if type == :ssh_forward
end

#template_labels(i) ⇒ Object



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

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

#template_labels_pods(i) ⇒ Object



195
196
197
198
199
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 195

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



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/picsolve_docker_builder/helpers/kubernetes_manager.rb', line 127

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