class Cangallo::Repo

Constants

VERSION

Attributes

images[R]
name[R]
path[R]
tags[R]

Public Class Methods

new(conf) click to toggle source
# File lib/cangallo/repo.rb, line 29
def initialize(conf)
  @conf = conf
  @path = File.expand_path(@conf["path"])
  @name = @conf["name"]
  @type = @conf["type"]
  @url  = @conf["url"]

  if !@type && @url
    @type = "remote"
  else
    @type = "local"
  end

  read_index
end

Public Instance Methods

add(name, data) click to toggle source
# File lib/cangallo/repo.rb, line 97
def add(name, data)
  data["creation-time"] = Time.now
  data["sha256"] = name
  @images[name] = data
end
add_image(file, data = {}) click to toggle source
# File lib/cangallo/repo.rb, line 103
def add_image(file, data = {})
  parent_sha256 = nil
  parent = nil
  parent_path = nil

  only_copy = data.delete("only_copy")

  if data["parent"]
    parent_sha256 = data["parent"]
    parent = self.images[parent_sha256]

    if !parent
      raise "Parent not found"
    end

    parent_path = File.expand_path(self.image_path(parent_sha256))
  end

  puts "Calculating image sha256 with libguestfs (it will take some time)"
  qcow2 = Cangallo::Qcow2.new(file)
  sha256 = qcow2.sha256
  sha256.strip! if sha256

  puts "Image SHA256: #{sha256}"

  puts "Copying file to repository"
  image_path = self.image_path(sha256)
  qcow2.copy(image_path, parent: parent_path, only_copy: only_copy)

  qcow2 = Cangallo::Qcow2.new(image_path)
  info = qcow2.info

  info_data = info.select do |k,v|
    %w{virtual-size format actual-size format-specific}.include?(k)
  end

  data.merge!(info_data)

  data["file-sha256"] = Digest::SHA256.file(file).hexdigest

  if parent
    qcow2.rebase("#{parent_sha256}.qcow2")
    data["parent"] = parent_sha256
  end

  self.add(sha256, data)
  self.write_index

  sha256
end
add_tag(tag, image) click to toggle source
# File lib/cangallo/repo.rb, line 175
def add_tag(tag, image)
  img = find(image)
  @tags[tag] = img
  write_index
end
ancestors(name) click to toggle source
# File lib/cangallo/repo.rb, line 217
def ancestors(name)
  ancestors = []

  image = get(name)
  ancestors << image["sha256"]

  while image["parent"]
    image = get(image["parent"])
    ancestors << image["sha256"]
  end

  ancestors
end
del_image(image) click to toggle source
# File lib/cangallo/repo.rb, line 154
def del_image(image)
  sha256 = find(image)

  raise %Q{Image "#{image}" does not exist} if !sha256

  path = image_path(sha256)
  begin
      File.delete(path)
  rescue Errno::ENOENT
      STDERR.puts "Image file not found"
  end

  @images.delete(sha256)

  @tags.select {|key, value| value == sha256 }.keys.each do |tag|
      @tags.delete(tag)
  end

  write_index
end
del_tag(tag) click to toggle source
# File lib/cangallo/repo.rb, line 181
def del_tag(tag)
  @tags.delete(tag)
  write_index
end
fetch() click to toggle source
# File lib/cangallo/repo.rb, line 235
def fetch
  return nil if @conf["type"] != "remote"

  uri = remote_url("index.yaml")

  open(uri, "r") do |f|
    data = f.read
    read_index(data)
  end

  write_index
end
find(name, search_tags = true) click to toggle source
# File lib/cangallo/repo.rb, line 186
def find(name, search_tags = true)
  length = name.length
  found = @images.select do |sha256, data|
    sha256[0, length] == name
  end

  if found && found.length > 0
    return found.first.first
  end

  if search_tags
    found = @tags.select do |tag, sha256|
      tag == name
    end
  end

  if found && found.length > 0
    return found.first[1]
  end

  nil
end
get(name) click to toggle source
# File lib/cangallo/repo.rb, line 209
def get(name)
  image = find(name)

  return nil if !image

  @images[image]
end
image_path(name) click to toggle source
# File lib/cangallo/repo.rb, line 85
def image_path(name)
  File.join(@path, "#{name}.qcow2")
end
index_data(images = {}, tags = {}, version = VERSION) click to toggle source
# File lib/cangallo/repo.rb, line 45
def index_data(images = {}, tags = {}, version = VERSION)
  {
    "version" => version,
    "images"  => images,
    "tags"    => tags
  }
end
index_path() click to toggle source
# File lib/cangallo/repo.rb, line 53
def index_path
  metadata_path("index")
end
metadata_path(name) click to toggle source
# File lib/cangallo/repo.rb, line 81
def metadata_path(name)
  File.join(@path, "#{name}.yaml")
end
pull(name) click to toggle source
# File lib/cangallo/repo.rb, line 256
def pull(name)
  image = get(name)

  raise "Image not found" if !image

  sha256 = image["sha256"]
  image_url = remote_image_url(sha256)
  image_path = image_path(sha256)
  cmd = "curl -o '#{image_path}' '#{image_url}'"

  STDERR.puts(cmd)

  system(cmd)
end
read_index(index = nil) click to toggle source
# File lib/cangallo/repo.rb, line 57
def read_index(index = nil)
  if !index
    if File.exist?(index_path)
      data = YAML.load(File.read(index_path))
    else
      data = index_data()
    end
  else
    data = YAML.load(index)
  end

  @images       = data["images"]
  @tags         = data["tags"]
  @reverse_tags = @tags.invert
end
remote_image_url(name) click to toggle source
# File lib/cangallo/repo.rb, line 93
def remote_image_url(name)
  remote_url("#{name}.qcow2")
end
remote_url(name) click to toggle source
# File lib/cangallo/repo.rb, line 89
def remote_url(name)
  URI.join(@url, name)
end
short_name(sha256) click to toggle source
# File lib/cangallo/repo.rb, line 271
def short_name(sha256)
  tag = @reverse_tags[sha256]

  if tag
    name = "#{tag}"
  else
    name = "#{sha256[0..15]}"
  end

  name
end
sign() click to toggle source
# File lib/cangallo/repo.rb, line 248
def sign
  Keybase.sign(index_path)
end
url() click to toggle source
# File lib/cangallo/repo.rb, line 231
def url
  @conf["url"]
end
verify() click to toggle source
# File lib/cangallo/repo.rb, line 252
def verify
  Keybase.verify(index_path)
end
write_index() click to toggle source
# File lib/cangallo/repo.rb, line 73
def write_index
  data = index_data(@images, @tags)

  open(metadata_path("index"), "w") do |f|
    f.write(data.to_yaml)
  end
end