class RightPublish::AptRepo

Constants

BIN_ALL_ARCH
BIN_EXTENSION
DEFAULT_APT_AUTO
DEFAULT_APT_DIR
DEFAULT_DESCRIPTION
REPO_KEY
REPO_OPTIONS
SRC_EXTENSION

Public Class Methods

pkg_parts(pkg_name) click to toggle source
# File lib/right_publish/repos/apt.rb, line 62
def self.pkg_parts(pkg_name)
  result = {:name=>nil, :version=>nil, :arch=>nil, :ext=>nil}
  if pkg_name.end_with?(SRC_EXTENSION)
    if /([A-Za-z0-9\.\-+]+)_([A-Za-z0-9\-\.:~]+)\.#{SRC_EXTENSION}\Z/.match(pkg_name)
      result[:name] = $1
      result[:version] = $2
      result[:ext] = SRC_EXTENSION
    end
  else
    if /([A-Za-z0-9\.\-+]+)_([A-Za-z0-9\-\.:~]+)_(#{@@all_archs.join('|')})\.#{BIN_EXTENSION}\Z/.match(pkg_name)
      result[:name] = $1
      result[:version] = $2
      result[:arch] = $3
      result[:ext] = BIN_EXTENSION
    end
  end
  result
end

Public Instance Methods

add(file_or_dir, target) click to toggle source
# File lib/right_publish/repos/apt.rb, line 23
def add(file_or_dir, target)
  repo_updates = {}

  # If we specified a target, let's make sure it's in our profile
  if target
    fail("specified distribution is not listed in this profile!") unless repo_config[:dists].include?(target)
  end

  pkgs = []
  get_pkg_list(file_or_dir, [BIN_EXTENSION, SRC_EXTENSION]) do |path|
    if path.end_with? BIN_EXTENSION and repo_config[:auto]
      arch = AptRepo.pkg_parts(path)[:arch] || fail("could not determine architecture for package: #{path}")
      fail("you probably want to specify a distribution target for binary packages!") unless target || arch == BIN_ALL_ARCH
    end
    pkgs << path
  end

  repo_path = File.join(Profile.config[:local_storage][:cache_dir], repo_config[:subdir])
  write_conf_file repo_path if repo_config[:auto]

  pkgs.each do |pkg|
    Profile.log("Adding package [#{pkg}]...")
    if repo_config[:auto]
      # If source package, remove existing sources so we don't get a hash clash
      auto_repo_remove(repo_path, pkg, target)
      auto_repo_add(repo_path, pkg, target)
    else
      trivial_repo_add(pkg)
    end
  end
  rebuild_index(repo_config[:subdir]) if not repo_config[:auto]
end
annotate(options={}) click to toggle source
Calls superclass method RightPublish::Repo#annotate
# File lib/right_publish/repos/apt.rb, line 56
def annotate(options={})
  options[:subdir] ||= File.join(repo_config[:subdir], 'pool', 'main')
  options[:filter] = ['*.deb', '*.dsc', '*.tar.gz']
  super(options)
end

Private Instance Methods

auto_repo_add(repo_path, pkg, target) click to toggle source
# File lib/right_publish/repos/apt.rb, line 83
def auto_repo_add(repo_path, pkg, target)
  targets = (target && Array(target)) || repo_config[:dists]
  targets.each do |t|
    sub_command = (pkg.end_with?(BIN_EXTENSION) && 'includedeb') || 'includedsc'
    ask_passphrase = (repo_config[:gpg_key_id]) ? "--ask-passphrase " : ""
    cmd = "reprepro #{ask_passphrase}-C main -b #{repo_path} #{sub_command} #{t} #{pkg}"
    if repo_config[:gpg_key_id]
      exited = shellout_with_password(cmd)
    else
      exited = system(cmd)
    end

    raise RuntimeError, "apt package installation failed; cannot continue publishing" unless exited
  end
end
auto_repo_remove(repo_path, pkg, target) click to toggle source
# File lib/right_publish/repos/apt.rb, line 99
def auto_repo_remove(repo_path, pkg, target)
  pkg_name = AptRepo.pkg_parts(pkg)[:name]
  filterlist  = "'$PackageType (== #{ (pkg.end_with?(BIN_EXTENSION) && 'deb') || 'dsc' }), Package (% #{pkg_name})'"

  Profile.log("Removing any packages files using filterlist #{filterlist}")

  targets = (target && Array(target)) || repo_config[:dists]
  targets.each do |t|
    ask_passphrase = (repo_config[:gpg_key_id]) ? "--ask-passphrase" : ""
    cmd = "reprepro #{ask_passphrase} -b #{repo_path} removefilter #{t} #{filterlist}"
    if repo_config[:gpg_key_id]
      exited = shellout_with_password(cmd)
    else
      exited = system(cmd)
    end
  end
end
dist_conf(dist) click to toggle source
# File lib/right_publish/repos/apt.rb, line 177
    def dist_conf(dist)
      <<EOF
Origin: RightScale
Codename: #{dist}
Version: 1.0
Architectures: #{@@supported_archs.join(' ')} source
Components: main
Description: #{repo_config[:description]}
#{(repo_config[:gpg_key_id] && "SignWith: #{repo_config[:gpg_key_id]}") || nil}

EOF
    end
rebuild_index(subdir) click to toggle source
# File lib/right_publish/repos/apt.rb, line 117
def rebuild_index(subdir)
  Profile.log("Rebuilding repository index...")
  do_in_subdir(subdir) do
    indexed = system("dpkg-scanpackages binaries /dev/null 2>/dev/null | gzip -c9 > Packages.gz")
    raise RuntimeError, "apt package installation failed; cannot continue publishing" unless indexed
    indexed = system("dpkg-scansources sources /dev/null 2>/dev/null | gzip -c9 > Sources.gz")
    raise RuntimeError, "apt package installation failed; cannot continue publishing" unless indexed
  end
end
trivial_repo_add(pkg) click to toggle source
# File lib/right_publish/repos/apt.rb, line 127
def trivial_repo_add(pkg)
  pkg_info = AptRepo.pkg_parts(pkg)

  if pkg_info[:ext].eql?(BIN_EXTENSION)
    sub_dir = File.join(repo_config[:subdir], 'binaries')
  else
    pkg_name = pkg_info[:name]
    src_file = Dir.glob("#{File.dirname(pkg)}/#{pkg_name}_*.orig.tar.gz")
    raise RuntimeError, "could not find original source for #{pkg}, missing or ambiguous." unless src_file.size == 1

    diff_file = pkg.sub(/#{SRC_EXTENSION}$/, 'diff.gz')
    sub_dir = File.join(repo_config[:subdir], 'sources')
    raise RuntimeError, "missing the debian diff file for #{pkg}." unless File.file?(diff_file)

    do_in_subdir(sub_dir) { prune_all("#{pkg_info[:name]}*.orig.tar.gz") }
    install_file(src_file[0], sub_dir)

    do_in_subdir(sub_dir) { prune_all("#{pkg_info[:name]}*.diff.gz") }
    install_file(diff_file, sub_dir)
  end

  do_in_subdir(sub_dir) { prune_all("#{pkg_info[:name]}_*#{pkg_info[:arch]}.#{pkg_info[:ext]}") }
  install_file(pkg, sub_dir)
end
write_conf_file(repo_path) click to toggle source
# File lib/right_publish/repos/apt.rb, line 152
def write_conf_file(repo_path)
  conf_dir = File.expand_path(File.join(repo_path, 'conf'))
  FileUtils.mkdir_p(conf_dir)
  distributions_file = File.join(conf_dir, 'distributions')
  File.open(distributions_file , 'wb' ) do |f|
    repo_config[:dists].each { |dist| f.puts(dist_conf(dist)) }
  end

  # We preseed this file with values that would be generated if this were
  # a precise distro. If we start this repo on trusty then it'll write 5.3.x
  # for the bdb version which is not backwards compatible. The precise versions
  # are forward compatible to trusty at least though.
  db_dir = File.expand_path(File.join(repo_path, 'db'))
  FileUtils.mkdir_p(db_dir)
  version_file = File.join(db_dir, 'version')
  unless File.exists?(version_file)
    File.open(version_file, 'wb') do |f|
      f.puts("4.8.2")
      f.puts("3.3.0")
      f.puts("bdb5.1.25")
      f.puts("bdb5.1.0")
    end
  end
end