Module: Aggkit::Ci

Defined in:
lib/aggkit/ci.rb

Instance Method Summary collapse

Instance Method Details

#baseimage(service) ⇒ Object

Базовое имя образа Например docker.rnds.pro/aggredator-mq



40
41
42
43
# File 'lib/aggkit/ci.rb', line 40

def baseimage service
  raise "Service name invalid: #{service.inspect}" if service.to_s.length < 2
  "docker.rnds.pro/aggredator-#{service}"
end

#clean_services(services, tag) ⇒ Object

Растегировать все образы для дальнейшего удаления. Помечает как latest для поддержки кеширования docker



188
189
190
191
192
193
194
195
196
# File 'lib/aggkit/ci.rb', line 188

def clean_services services, tag
  [services].flatten.each do |service|
    tagimage! workimage(service, tag), workimage(service, 'latest'), ignoreerror: true
    tagimage! devimage(service, tag), workimage(service, 'latest'), ignoreerror: true
    tagimage! stageimage(service, tag), workimage(service, 'latest'), ignoreerror: true
    tagimage! releaseimage(service, tag), workimage(service, 'latest'), ignoreerror: true
    untagservice(service, tag)
  end
end

#devimage(service, tag) ⇒ Object

Образ с модификатором протестированной автотестами версии Например docker.rnds.pro/aggredator-mq-dev:7e6420b5



63
64
65
# File 'lib/aggkit/ci.rb', line 63

def devimage service, tag
  promotedimage(service, 'dev', tag)
end

#execute(cmd) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/aggkit/ci.rb', line 20

def execute cmd
  puts "  - executing: #{cmd}"
  result = `#{cmd}`
  puts result
  if !$?.success?
    raise "Execution failed cmd: #{cmd.inspect}"
  end
  result
end

#info(message) ⇒ Object



16
17
18
# File 'lib/aggkit/ci.rb', line 16

def info message
  puts " => #{message}"
end

#label!(image, label, value) ⇒ Object



102
103
104
105
106
107
# File 'lib/aggkit/ci.rb', line 102

def label! image, label, value
  raise "Image label invalid: #{label.inspect}" if label.to_s.length < 2
  raise "Image label value invalid: #{value.inspect}" if value.to_s.length < 2

  execute("echo #{image} | docker build -t #{image} --label=\"#{label.to_s}=#{value.to_s}\" - ")
end

#log_action(action) ⇒ Object



12
13
14
# File 'lib/aggkit/ci.rb', line 12

def log_action action
  puts " => #{action}"
end

#promote!(service, tag, stage, fromstage: nil) ⇒ Object

Продвинуть текущий образ сервиса по уровню - добавить модификатор и залить в репозиторий



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/aggkit/ci.rb', line 120

def promote! service, tag, stage, fromstage: nil
  fromimage = if fromstage
    promotedimage(service, fromstage, tag)
  else
    workimage(service, tag)
  end

  toimage = promotedimage(service, stage, tag)

  log_action "Promote #{fromimage} to #{toimage}"
  return tagimage! fromimage, toimage, push: true
end

#promote_services_to_dev!(services, tag) ⇒ Object

Продвинуть список образов или упасть с ошибкой



151
152
153
154
155
# File 'lib/aggkit/ci.rb', line 151

def promote_services_to_dev! services, tag
  [services].flatten.each do |service|
    promote_to_dev!(service, tag)
  end
end

#promote_services_to_stage!(services, tag) ⇒ Object

Продвинуть список образов или упасть с ошибкой



158
159
160
161
162
# File 'lib/aggkit/ci.rb', line 158

def promote_services_to_stage! services, tag
  [services].flatten.each do |service|
    promote_to_stage!(service, tag)
  end
end

#promote_services_to_tag!(services, tag, newtag) ⇒ Object

Протегировать образы до указанного тега



165
166
167
168
169
# File 'lib/aggkit/ci.rb', line 165

def promote_services_to_tag! services, tag, newtag
  [services].flatten.each do |service|
    promote_to_tag!(service, tag, newtag)
  end
end

#promote_to_dev!(service, tag) ⇒ Object

Продвинуть текущий образ по уровню - добавить модификатор dev(протестировано) и залить в репозиторий



134
135
136
# File 'lib/aggkit/ci.rb', line 134

def promote_to_dev! service, tag
  promote!(service, tag, 'dev')
end

#promote_to_stage!(service, tag) ⇒ Object

Продвинуть текущий образ по уровню - добавить модификатор stage(стабильно) и залить в репозиторий



139
140
141
142
143
# File 'lib/aggkit/ci.rb', line 139

def promote_to_stage! service, tag
  promoted = tagimage!(devimage(service, tag), stageimage(service, tag), push: true)
  # Тегируем этот образ как latest
  return tagimage!(promoted, stageimage(service, 'latest'), push: true)
end

#promote_to_tag!(service, tag, newtag) ⇒ Object

Продвинуть стабильный образ до указанного тега



146
147
148
# File 'lib/aggkit/ci.rb', line 146

def promote_to_tag! service, tag, newtag
  return tagimage!(devimage(service, tag), stageimage(service, newtag), push: true)
end

#promotedimage(service, stage, tag) ⇒ Object

Образ с модификатором версии Например docker.rnds.pro/aggredator-mq-dev:7e6420b5



55
56
57
58
59
# File 'lib/aggkit/ci.rb', line 55

def promotedimage service, stage, tag
  raise "Service stage invalid: #{stage.inspect}" if stage.to_s.length < 2
  raise "Service tag invalid: #{tag.inspect}" if tag.to_s.length < 2
  "#{baseimage(service)}-#{stage}:#{tag}"
end

#pull_images_cache(services, tag) ⇒ Object

Попытаться взять все модификаторы образов из репозитория Скачивает образы и тегирует их как workimage



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/aggkit/ci.rb', line 175

def pull_images_cache services, tag
  log_action "Puling images#{[services].flatten.inspect} from cache...."
  [services].flatten.each do |service|
    execute("docker pull #{devimage(service, tag)} 2> /dev/null || true")
    execute("docker pull #{stageimage(service, tag)} 2> /dev/null || true")
    execute("docker pull #{releaseimage(service, tag)} 2> /dev/null || true")
    tagimage! devimage(service, tag), workimage(service, tag), ignoreerror: true
    tagimage! stageimage(service, tag), workimage(service, tag), ignoreerror: true
    tagimage! releaseimage(service, tag), workimage(service, tag), ignoreerror: true
  end
end

#releaseimage(service, tag) ⇒ Object

Образ с модификатором релизной версии Например docker.rnds.pro/aggredator-mq-release:7e6420b5



75
76
77
# File 'lib/aggkit/ci.rb', line 75

def releaseimage service, tag
  promotedimage(service, 'release', tag)
end

#rmimage!(image) ⇒ Object

Удалить образ образ тегом



97
98
99
100
# File 'lib/aggkit/ci.rb', line 97

def rmimage! image
  log_action "Remove #{image.inspect}"
  execute("docker rmi #{image} &> /dev/null || true")
end

#ssh_deploy(services, env, sshserver, tag, stage) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/aggkit/ci.rb', line 198

def ssh_deploy services, env, sshserver, tag, stage
  services = [services].flatten
  log_action "Deploy [#{services.inspect}] tag:#{tag.inspect} stage:#{stage.inspect} to #{sshserver.inspect}"
  with_ssh sshserver do |sockname|
    env_config = JSON(`agg #{env} --show --release`)
    envs = env_config['envs']
    config_file = env_config['config_file'].to_s
    envs['DOCKER_HOST'] = "unix://#{sockname}"
    envs['CORE_TAG'] = tag
    envs['CORE_SUFFIX'] = "-#{stage}"

    localid = execute("docker info | grep ID").strip

    Aggkit::Env.with_env(envs) do
      remoteid = execute("docker info | grep ID").strip

      if localid == remoteid
        raise "Can't get access to remote Docker"
      end

      execute('docker-compose ps')
      execute('docker-compose pull')

      consul = execute('docker ps | grep consul').split(' ').first.strip
      puts "CONSULT ID: #{consul}"

      if !config_file.empty?
        execute("docker exec -i #{consul} waiter.rb -t 20 --consul")
        execute("docker exec -i #{consul} consul.rb --init --override --config - < #{config_file}")
      end

      execute('docker-compose up -d')

      services.each do |service|
        deployed = promotedimage(service, stage, tag)
        current = promotedimage(service, stage, 'current')
        tagimage! deployed, current
        untagservice(service, tag)
      end

    end
  end
end

#stageimage(service, tag) ⇒ Object

Образ с модификатором стабильной версии Например docker.rnds.pro/aggredator-mq-stage:7e6420b5



69
70
71
# File 'lib/aggkit/ci.rb', line 69

def stageimage service, tag
  promotedimage(service, 'stage', tag)
end

#tagimage!(image, newimage, push: false, ignoreerror: false) ⇒ Object

Протегировать образ тегом



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/aggkit/ci.rb', line 80

def tagimage! image, newimage, push: false, ignoreerror: false
  log_action "Tag #{image.inspect} as #{newimage.inspect}"

  if ignoreerror
    execute("docker tag #{image} #{newimage} 2> /dev/null || true")
  else
    execute("docker tag #{image} #{newimage}")
  end

  if push
    execute("docker push #{newimage}")
  end

  return newimage
end

#untagservice(service, tag) ⇒ Object

Растегировать все модификатора образа сервиса и возможно удалить его



110
111
112
113
114
115
116
117
# File 'lib/aggkit/ci.rb', line 110

def untagservice service, tag
  if tag != 'latest'
    rmimage! workimage(service, tag)
    rmimage! devimage(service, tag)
    rmimage! stageimage(service, tag)
    rmimage! releaseimage(service, tag)
  end
end

#with_ssh(server, user: 'root', &block) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/aggkit/ci.rb', line 242

def with_ssh server, user: 'root', &block
  file = Tempfile.new
  @ssh_sockname = file.path
  file.unlink
  @ssh_pid = spawn("ssh -NL #{@ssh_sockname}:/var/run/docker.sock root@#{server}")
  sleep 5
  yield(@ssh_sockname)
ensure
  Process.kill(:SIGTERM, @ssh_pid)
  sleep 5
  Process.wait2(@ssh_pid, Process::WNOHANG)
  FileUtils.rm_f(@ssh_sockname)
end

#workimage(service, tag) ⇒ Object

Текущее имя образа без модификаторов продвижения, но с тегом Например docker.rnds.pro/aggredator-mq:7e6420b5



48
49
50
51
# File 'lib/aggkit/ci.rb', line 48

def workimage service, tag
  raise "Service tag invalid: #{tag.inspect}" if tag.to_s.length < 2
  "#{baseimage(service)}:#{tag}"
end