inspec/lib/resources/apt.rb

138 lines
3.5 KiB
Ruby
Raw Normal View History

2015-10-10 17:53:39 +00:00
# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
# Verifies apt and ppa repositories
#
# Usage:
# describe ppa('ubuntu-wine/ppa') do
# it { should exist }
# it { should be_enabled }
# end
#
# it also understands a ppa url
# describe ppa('ppa:ubuntu-wine/ppa') do
# it { should exist }
# it { should be_enabled }
# end
#
# The following ppa formats are supported:
# - ubuntu-wine/ppa
# - ppa:ubuntu-wine/ppa
# - http://ppa.launchpad.net/juju/stable/ubuntu
#
# Install a ppa as following:
# apt-get install python-software-properties
# apt-get install software-properties-common
# add-apt-repository ppa:ubuntu-wine/ppa
class AptRepository < Vulcano.resource(1)
name 'apt'
def initialize(ppa_name)
@deb_url = nil
# check if the os is ubuntu or debian
if vulcano.os.debian?
@deb_url = determine_ppa_url(ppa_name)
else
# this resource is only supported on ubuntu and debian
2015-10-10 21:29:44 +00:00
skip_resource 'The `apt` resource is not supported on your OS yet.'
2015-10-10 17:53:39 +00:00
end
end
def exists?
find_repo.count > 0
end
def enabled?
return false if find_repo.count == 0
actives = find_repo.map { |repo| repo[:active] }
actives = actives.uniq
actives.size == 1 && actives[0] = true
end
def to_s
"apt #{@deb_url}"
end
private
def find_repo
read_debs.select { |repo| repo[:url] == @deb_url && repo[:type] == 'deb' }
end
# read
def read_debs
return @repo_cache if defined?(@repo_cache)
2015-10-10 17:53:39 +00:00
# load all lists
cmd = vulcano.command("find /etc/apt/ -name \*.list -exec sh -c 'cat {} || echo -n' \\;")
# @see https://help.ubuntu.com/community/Repositories/CommandLine#Explanation_of_the_Repository_Format
@repo_cache = cmd.stdout.chomp.split("\n").each_with_object([]) do |raw_line, lines|
active = true
# detect if the repo is commented out
line = raw_line.gsub(/^(#\s*)*/, '')
active = false if raw_line != line
# eg.: deb http://archive.ubuntu.com/ubuntu/ wily main restricted
parse_repo = /^\s*(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/.match(line)
# check if we got any result and the second param is an url
next if parse_repo.nil? || !parse_repo[2] =~ /\A#{URI.regexp(%w{http https})}\z/
# map data
repo = {
type: parse_repo[1],
url: parse_repo[2],
distro: parse_repo[3],
components: parse_repo[4].chomp.split(' '),
active: active,
}
next unless ['deb', 'deb-src'].include? repo[:type]
lines.push(repo)
end
end
# resolves ppa urls
# @see http://bazaar.launchpad.net/~ubuntu-core-dev/software-properties/main/view/head:/softwareproperties/ppa.py
def determine_ppa_url(ppa_url)
# verify if we have the url already, then just return
is_url = ppa_url =~ /\A#{URI.regexp(%w{http https})}\z/
return ppa_url if is_url == 0
# otherwise start generating the ppa url
# special care if the name stats with :
ppa_url = ppa_url.split(':')[1] if ppa_url.start_with?('ppa:')
# parse ppa owner and repo
ppa_owner, ppa_repo = ppa_url.split('/')
ppa_repo = 'ppa' if ppa_repo.nil?
# construct new ppa url and return it
format('http://ppa.launchpad.net/%s/%s/ubuntu', ppa_owner, ppa_repo)
end
end
# for compatability with serverspec
# this is deprecated syntax and will be removed in future versions
class PpaRepository < AptRepository
name 'ppa'
def exists?
deprecated
super()
end
def enabled?
deprecated
super()
end
def deprecated
warn '[DEPRECATION] `ppa(reponame)` is deprecated. Please use `apt(reponame)` instead.'
end
end