class DockerCake

Attributes

registry[RW]

Public Class Methods

new(url: nil, user: nil, password: nil) click to toggle source
# File lib/docker_cake.rb, line 9
def initialize(url: nil, user: nil, password: nil)
  @registry ||= RegistryApiClient.new(user: user, password: password, url: url)
end

Public Instance Methods

compare_versions(repo_name, filter: /.+/, max: 10) click to toggle source
# File lib/docker_cake.rb, line 18
def compare_versions(repo_name, filter: /.+/, max: 10)
  tags = registry.tags(repo_name, false)['tags']

  if ENV['DEBUG']
    puts "Found tags: #{tags.join(", ")}"
  end

  tags.select! {|t| t =~ filter}

  selected_tags = tags.last(max)

  if ENV['DEBUG']
    puts "Analyzing #{selected_tags.size} tags: #{selected_tags.join(", ")}..."
  end

  manifests = {}
  procs = selected_tags.map do |tag|
    lambda { manifests[tag] = registry.manifest_layers(repo_name, tag) }
  end
  registry.in_parallel(procs)
  #selected_tags.each do |tag|
  #  manifests[tag] = registry.manifest_layers(repo_name, tag)
  #  #pp manifests[tag]
  #end

  manifests = manifests.sort_by do |tag, list|
    list.map {|l| l['created'] }.max
  end.to_h

  images_map = {}
  counted_layers = []
  result = []

  manifests.each do |tag, layers|
    stats = {name: tag, size: 0, add_img: 0, reuse_img: 0, add_size: 0, layers: 0, date: Time.at(0).to_s}

    map_key = manifests[tag].map {|l| l['blobSum']}.join(',')
    if images_map[map_key]
      stats[:same_as] = images_map[map_key]
    end
    images_map[map_key] ||= tag

    manifests[tag].each do |layer|
      next if layer['size'] == nil

      stats[:size] += layer['size'] || 0
      stats[:layers] += 1
      stats[:date] = layer['created'] if layer['created'] > stats[:date]

      layer_key = layer['blobSum'] #+ "_" + layer['id']

      if counted_layers.include?(layer_key)
        stats[:reuse_img] += 1
      else
        stats[:add_img] += 1
        stats[:add_size] += layer['size'] || 0
      end

      counted_layers << layer_key
    end

    #puts "#{tag} -> #{stats}"
    result << stats
  end

  puts print_comparison(result)
end
print_comparison(result) click to toggle source
print_manifest(manifest) click to toggle source
repo_info(name, tag = 'latest') click to toggle source
# File lib/docker_cake.rb, line 13
def repo_info(name, tag = 'latest')
  manifest = registry.manifest_layers(name, tag)
  puts print_manifest(manifest)
end
size_to_human(size) click to toggle source
# File lib/docker_cake.rb, line 133
def size_to_human(size)
  return '0' unless size

  if size > 1_000_000_000
    "#{(size / 1_000_000_000.0).round(3)} GB"
  elsif size > 1_000_000
    "#{(size / 1_000_000.0).round(3)} MB"
  elsif size > 1_000
    "#{(size / 1_000.0).round(3)} KB"
  else
    "#{size} Bytes"
  end
end