module Aggkit::Ci

Public Instance Methods

baseimage(service) click to toggle source

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

# File lib/aggkit/ci.rb, line 39
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) click to toggle source

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

# File lib/aggkit/ci.rb, line 194
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) click to toggle source

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

# File lib/aggkit/ci.rb, line 64
def devimage(service, tag)
  promotedimage(service, 'dev', tag)
end
execute(cmd) click to toggle source
# File lib/aggkit/ci.rb, line 20
def execute(cmd)
  puts "  - executing: #{cmd}"
  result = `#{cmd}`
  puts result
  raise "Execution failed cmd: #{cmd.inspect}" unless $?.success?

  result
end
info(message) click to toggle source
# File lib/aggkit/ci.rb, line 16
def info(message)
  puts " => #{message}"
end
label!(image, label, value) click to toggle source
# File lib/aggkit/ci.rb, line 101
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}=#{value}\" - ")
end
log_action(action) click to toggle source
# File lib/aggkit/ci.rb, line 12
def log_action(action)
  puts " => #{action}"
end
promote!(service, tag, stage, fromstage: nil) click to toggle source

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

# File lib/aggkit/ci.rb, line 119
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}"
  tagimage! fromimage, toimage, push: true
end
promote_services_to_dev!(services, tag) click to toggle source

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

# File lib/aggkit/ci.rb, line 150
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) click to toggle source

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

# File lib/aggkit/ci.rb, line 157
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) click to toggle source

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

# File lib/aggkit/ci.rb, line 164
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) click to toggle source

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

# File lib/aggkit/ci.rb, line 133
def promote_to_dev!(service, tag)
  promote!(service, tag, 'dev')
end
promote_to_stage!(service, tag) click to toggle source

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

# File lib/aggkit/ci.rb, line 138
def promote_to_stage!(service, tag)
  promoted = tagimage!(devimage(service, tag), stageimage(service, tag), push: true)
  # Тегируем этот образ как latest
  tagimage!(promoted, stageimage(service, 'latest'), push: true)
end
promote_to_tag!(service, tag, newtag) click to toggle source

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

# File lib/aggkit/ci.rb, line 145
def promote_to_tag!(service, tag, newtag)
  tagimage!(devimage(service, tag), workimage(service, newtag), push: true)
end
promotedimage(service, stage, tag) click to toggle source

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

# 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) click to toggle source

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

# File lib/aggkit/ci.rb, line 172
def pull_images_cache(services, tag)
  log_action "Puling images#{[services].flatten.inspect} from cache...."
  [services].flatten.each do |service|
    execute("docker pull #{workimage(service, tag)} 2> /dev/null || true")
    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
push_images_cache(services, tag) click to toggle source

Залить образы в репозиторий

# File lib/aggkit/ci.rb, line 186
def push_images_cache(services, tag)
  log_action "Pushing images#{[services].flatten.inspect} to cache...."
  [services].flatten.each do |service|
    tagimage! workimage(service, tag), workimage(service, tag), push: true
  end
end
releaseimage(service, tag) click to toggle source

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

# File lib/aggkit/ci.rb, line 76
def releaseimage(service, tag)
  promotedimage(service, 'release', tag)
end
rmimage!(image) click to toggle source

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

# File lib/aggkit/ci.rb, line 96
def rmimage!(image)
  log_action "Remove #{image.inspect}"
  execute("docker rmi #{image} &> /dev/null || true")
end
ssh_core_deploy(services, env, sshserver, tag, stage) click to toggle source
# File lib/aggkit/ci.rb, line 223
def ssh_core_deploy(services, env, sshserver, tag, stage)
  with_remote_docker services, env, sshserver, tag, stage do |config, _environment|
    config_file = config['config_file'].to_s

    execute('docker-compose ps')
    execute('docker-compose pull')
    execute('docker-compose up -t 30 -d consul')

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

    unless config_file.empty?
      execute("docker exec -i #{consul} aggwait -t 20 --consul")
      execute("docker exec -i #{consul} aggconsul --init --config - < #{config_file}")
    end

    # echo " * Consul ready"
    # echo " * Updatting database..."
    execute('docker-compose up -t 30 -d db')
    sleep 5
    # echo " * Db ready"
    # echo " * Bootstrapping admin..."
    execute('docker-compose run --rm -T admin /home/app/docker/bootstrap.rb')
    sleep 5
    # echo " * Bootstrapping complete"
    # echo " * Updating all containers..."
    execute('docker-compose up -t 30 -d')
    # echo " * Containers ready"
  end
end
ssh_deploy(services, env, sshserver, tag, stage) click to toggle source
# File lib/aggkit/ci.rb, line 204
def ssh_deploy(services, env, sshserver, tag, stage)
  with_remote_docker services, env, sshserver, tag, stage do |config, _environment|
    config_file = config['config_file'].to_s

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

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

    unless config_file.empty?
      execute("docker exec -i #{consul} aggwait -t 20 --consul")
      execute("docker exec -i #{consul} aggconsul --init --config - < #{config_file}")
    end

    execute('docker-compose up -t 30 -d')
  end
end
stageimage(service, tag) click to toggle source

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

# File lib/aggkit/ci.rb, line 70
def stageimage(service, tag)
  promotedimage(service, 'stage', tag)
end
tagimage!(image, newimage, push: false, ignoreerror: false) click to toggle source

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

# File lib/aggkit/ci.rb, line 81
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

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

  newimage
end
untagservice(service, tag) click to toggle source

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

# File lib/aggkit/ci.rb, line 109
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_remote_docker(services, env, sshserver, tag, stage) { |env_config, environment| ... } click to toggle source
# File lib/aggkit/ci.rb, line 254
def with_remote_docker(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 |environment|
      remoteid = execute('docker info | grep ID').strip

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

      yield(env_config, environment)

      services.each do |service|
        deployed = promotedimage(service, stage, tag)
        current = promotedimage(service, stage, 'current')
        tagimage! deployed, current
        untagservice(service, tag)
      end
    end
  end
end
with_ssh(server, user: 'root') { |ssh_sockname| ... } click to toggle source
# File lib/aggkit/ci.rb, line 284
def with_ssh(server, user: 'root')
  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) click to toggle source

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

# File lib/aggkit/ci.rb, line 47
def workimage(service, tag)
  raise "Service tag invalid: #{tag.inspect}" if tag.to_s.length < 2

  "#{baseimage(service)}:#{tag}"
end