class apt {

    file { "/var/cache/apt/local-archives":
        ensure => directory,
        mode   => 0755,
        owner  => root,
        group  => root,
    }

    exec { "apt-get-update":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin",
        command     => "apt-get update",
        refreshonly => true,
    }

}


# Configure /etc/apt/sources.list
#
# === Global variables
#
#   $apt_archive_url:
#       Base URL of archive repository. Defaults to http://archive.ubuntu.com/ubuntu/.
#   $apt_security_url:
#       Base URL of security repository. Defaults to http://security.ubuntu.com/ubuntu/.
#
class apt::sources {

    tag("bootstrap")

    include apt

    if !$apt_archive_url {
        $apt_archive_url = "http://archive.ubuntu.com/ubuntu/"
    }
    if !$apt_security_url {
        $apt_security_url = "http://security.ubuntu.com/ubuntu/"
    }

    file { "/etc/apt/sources.list":
        ensure  => present,
        mode    => 0644,
        owner   => root,
        group   => root,
        content => template("apt/sources.list.erb"),
        notify  => Exec["apt-get-update"],
    }

}


# Install apt-cacher server
#
class apt::cacher {

    package { "apt-cacher":
        ensure => installed,
    }

    augeas { "apt-cacher-autostart":
        context => "/files/etc/default/apt-cacher",
        changes => ["set AUTOSTART 1"],
        require => Package["apt-cacher"],
    }

    file { "/etc/apt-cacher/apt-cacher.conf":
        ensure => present,
        source => [ "puppet:///files/apt/apt-cacher.conf",
                    "puppet:///modules/apt/apt-cacher.conf", ],
        mode   => 0644,
        owner  => root,
        group  => root,
        notify => Service["apt-cacher"],
    }

    service { "apt-cacher":
        ensure  => running,
        enable  => true,
        require => Package["apt-cacher"],
    }

}

# Mirroring tool for apt repositories
#
# === Global variables
#
#   $aptmirror_threads:
#       Number of download threads to use, defaults to 5.
#
#   $aptmirror_server:
#       Server to use for mirroring, defaults to
#       http://archive.ubuntu.com/ubuntu
#
#   $aptmirror_list:
#       List of Ubuntu versions to mirror, defaults to [ "lucid" ].
#
class apt::mirror {

    if ! $aptmirror_threads {
        $aptmirror_threads = 10
    }

    if ! $aptmirror_server {
        $aptmirror_server = "http://archive.ubuntu.com/ubuntu"
    }

    if ! $aptmirror_list {
        $aptmirror_list = [ "lucid" ]
    }

    package { "apt-mirror":
        ensure => installed,
    }

    file { "/etc/apt/miror.list":
        ensure  => present,
        name    => $operatingsystem ? {
            centos  => "/etc/apt-mirror.list",
            default => "/etc/apt/miror.list",
        },
        content => template("apt/mirror.list.erb"),
        mode    => 0644,
        owner   => root,
        group   => root,
        require => Package["apt-mirror"],
    }

}


# Install .deb package.
#
# === Parameters
#
#   $name:
#       Package name.
#   $ensure:
#       Ensure package is absent or installed.
#   $source:
#       Source URL to .deb file.
#
# === Sample usage
#
# apt::package { "python-igraph":
#     ensure => installed,
#     source => "http://cneurocvs.rmki.kfki.hu/packages/binary/python-igraph_0.5.2_i386.deb",
# }
#
define apt::package($ensure, $source) {

    include apt

    $filename = regsubst($source, '.*/([^/]+)$', '\1')

    custom::file { "/var/cache/apt/local-archives/${filename}":
        ensure  => $ensure ? {
            installed => present,
            default   => absent,
        },
        source  => $source,
        mode    => 0644,
        owner   => root,
        group   => root,
        require => File["/var/cache/apt/local-archives"],
    }

    package { "${name}":
        ensure   => $ensure,
        source   => "/var/cache/apt/local-archives/${filename}",
        provider => dpkg,
        require  => Custom::File["/var/cache/apt/local-archives/${filename}"],
    }

}


# Add apt repository.
#
# === Global variables
#
#   $apt_proxy:
#       APT proxy host.
#
# === Parameters
#
#   $name:
#       Repository name.
#   $source:
#       Repository URL.
#   $dist:
#       Distribution name. Defaults to $lsbdistcodename.
#   $components
#       Repository components. Defaults to "main".
#   $key:
#       GPG key id.
#   $keyserver:
#       GPG keyserver uri.
#   $priority:
#       Set priority for this repository.
#   $label:
#       Set priority based on repository label.
#   $use_proxy:
#       Use apt proxy (if set). Defaults to true.
#   $use_source:
#       Use source packages. Defaults to false.
#
# === Sample usage
#
# apt::repo { "deb.torproject.org":
#     source    => "http://deb.torproject.org/torproject.org",
#     key       => "886DDD89",
#     keyserver => "hkp://keys.gnupg.net",
# }
#
define apt::repo($ensure, $source, $dist="", $components="main",
                 $key="", $keyserver="", $priority="", $label="",
                 $use_proxy=true, $use_source=false) {

    tag("bootstrap")

    include apt

    if $dist {
        $dist_real = $dist
    } else {
        $dist_real = $lsbdistcodename
    }

    if $apt_proxy and $use_proxy {
        $source_real = regsubst($source, "^([^:]+://)(.+)$", "\\1$apt_proxy/\\2")
    } else {
        $source_real = $source
    }

    if $http_proxy and $use_proxy {
        $http_proxy_real = $http_proxy
    } else {
        $http_proxy_real = ""
    }

    if $use_source {
        $content = "deb ${source_real} ${dist_real} ${components}\ndeb-src ${source_real} ${dist_real} ${components}\n"
    } else {
        $content = "deb ${source_real} ${dist_real} ${components}\n"
    }

    file { "/etc/apt/sources.list.d/${name}.list":
        ensure  => $ensure,
        mode    => 0644,
        owner   => root,
        group   => root,
        content => $content,
        notify  => Exec["apt-get-update"],
    }

    if $key and $keyserver {
        case $keyserver {
            /^hkp:.*/: {
                $command = "apt-key adv --keyserver ${keyserver} --recv ${key}"
            }
            default: {
                $command = "apt-key adv --fetch ${keyserver}"
            }
        }

        exec { "apt-key-add-${key}":
            environment => $http_proxy_real ? {
                ""      => undef,
                default => "http_proxy=${http_proxy_real}",
            },
            path        => "/bin:/usr/bin:/sbin:/usr/sbin",
            command     => $command,
            unless      => "apt-key list | grep '\\b${key}\\b'",
            notify      => Exec["apt-get-update"],
        }
    }

    if $priority {
        $origin = regsubst($source, "^([^:]+://)([^/]+)/.*$", "\\2")
        file { "/etc/apt/preferences.d/${name}.pref":
            ensure  => $ensure,
            mode    => 0644,
            owner   => root,
            group   => root,
            content => $label ? {
                ""      => "Package: *\nPin: origin ${origin}\nPin-Priority: ${priority}\n",
                default => "Package: *\nPin: release l=${label}\nPin-Priority: ${priority}\n",
            }
        }
    }

}


# Add Ubuntu partner (3rd party sofware) repository
#
class apt::repo::partner {

    apt::repo { "partner":
        ensure     => present,
        source     => "http://archive.canonical.com/ubuntu/",
        components => "partner",
    }

}
