diff --git a/acceptance/lib/puppet/acceptance/install_utils.rb b/acceptance/lib/puppet/acceptance/install_utils.rb index 1891b6502..2888c6c2b 100644 --- a/acceptance/lib/puppet/acceptance/install_utils.rb +++ b/acceptance/lib/puppet/acceptance/install_utils.rb @@ -1,202 +1,202 @@ require 'open-uri' require 'open3' require 'uri' module Puppet module Acceptance module InstallUtils PLATFORM_PATTERNS = { :redhat => /fedora|el|centos/, :debian => /debian|ubuntu/, :debian_ruby18 => /debian|ubuntu-lucid|ubuntu-precise/, :solaris => /solaris/, :windows => /windows/, }.freeze # Installs packages on the hosts. # # @param hosts [Array] Array of hosts to install packages to. # @param package_hash [Hash{Symbol=>Array>}] # Keys should be a symbol for a platform in PLATFORM_PATTERNS. Values # should be an array of package names to install, or of two element # arrays where a[0] is the command we expect to find on the platform # and a[1] is the package name (when they are different). # @param options [Hash{Symbol=>Boolean}] # @option options [Boolean] :check_if_exists First check to see if # command is present before installing package. (Default false) # @return true def install_packages_on(hosts, package_hash, options = {}) check_if_exists = options[:check_if_exists] hosts = [hosts] unless hosts.kind_of?(Array) hosts.each do |host| package_hash.each do |platform_key,package_list| if pattern = PLATFORM_PATTERNS[platform_key] if pattern.match(host['platform']) package_list.each do |cmd_pkg| if cmd_pkg.kind_of?(Array) command, package = cmd_pkg else command = package = cmd_pkg end if !check_if_exists || !host.check_for_package(command) host.logger.notify("Installing #{package}") additional_switches = '--allow-unauthenticated' if platform_key == :debian host.install_package(package, additional_switches) end end end else raise("Unknown platform '#{platform_key}' in package_hash") end end end return true end def fetch(base_url, file_name, dst_dir) FileUtils.makedirs(dst_dir) src = "#{base_url}/#{file_name}" dst = File.join(dst_dir, file_name) if File.exists?(dst) logger.notify "Already fetched #{dst}" else logger.notify "Fetching: #{src}" logger.notify " and saving to #{dst}" open(src) do |remote| File.open(dst, "w") do |file| FileUtils.copy_stream(remote, file) end end end return dst end def fetch_remote_dir(url, dst_dir) logger.notify "fetch_remote_dir (url: #{url}, dst_dir #{dst_dir})" if url[-1, 1] !~ /\// url += '/' end url = URI.parse(url) chunks = url.path.split('/') dst = File.join(dst_dir, chunks.last) #determine directory structure to cut #only want to keep the last directory, thus cut total number of dirs - 2 (hostname + last dir name) cut = chunks.length - 2 wget_command = "wget -nv -P #{dst_dir} --reject \"index.html*\",\"*.gif\" --cut-dirs=#{cut} -np -nH --no-check-certificate -r #{url}" logger.notify "Fetching remote directory: #{url}" logger.notify " and saving to #{dst}" logger.notify " using command: #{wget_command}" #in ruby 1.9+ we can upgrade this to popen3 to gain access to the subprocess pid result = `#{wget_command} 2>&1` result.each_line do |line| logger.debug(line) end if $?.to_i != 0 raise "Failed to fetch_remote_dir '#{url}' (exit code #{$?}" end dst end def stop_firewall_on(host) case host['platform'] when /debian/ on host, 'iptables -F' when /fedora|el-7/ on host, puppet('resource', 'service', 'firewalld', 'ensure=stopped') when /el|centos/ on host, puppet('resource', 'service', 'iptables', 'ensure=stopped') when /ubuntu/ on host, puppet('resource', 'service', 'ufw', 'ensure=stopped') else logger.notify("Not sure how to clear firewall on #{host['platform']}") end end def install_repos_on(host, sha, repo_configs_dir) platform = host['platform'].with_version_codename platform_configs_dir = File.join(repo_configs_dir,platform) case platform when /^(fedora|el|centos)-(\d+)-(.+)$/ variant = (($1 == 'centos') ? 'el' : $1) fedora_prefix = ((variant == 'fedora') ? 'f' : '') version = $2 arch = $3 rpm = fetch( "http://yum.puppetlabs.com", "puppetlabs-release-%s-%s.noarch.rpm" % [variant, version], platform_configs_dir ) pattern = "pl-puppet-%s-%s-%s%s-%s.repo" repo_filename = pattern % [ sha, variant, fedora_prefix, version, arch ] repo = fetch( "http://builds.puppetlabs.lan/puppet/%s/repo_configs/rpm/" % sha, repo_filename, platform_configs_dir ) - link = "http://builds.puppetlabs.lan/puppet/%s/repos/%s/%s/products/%s/" % [sha, variant, version, arch] + link = "http://builds.puppetlabs.lan/puppet/%s/repos/%s/%s%s/products/%s/" % [sha, variant, fedora_prefix, version, arch] if not link_exists?(link) - link = "http://builds.puppetlabs.lan/puppet/%s/repos/%s/%s/devel/%s/" % [sha, variant, version, arch] + link = "http://builds.puppetlabs.lan/puppet/%s/repos/%s/%s%s/devel/%s/" % [sha, variant, fedora_prefix, version, arch] end if not link_exists?(link) raise "Unable to reach a repo directory at #{link}" end repo_dir = fetch_remote_dir(link, platform_configs_dir) on host, "rm -rf /root/*.repo; rm -rf /root/*.rpm; rm -rf /root/#{arch}" scp_to host, rpm, '/root' scp_to host, repo, '/root' scp_to host, repo_dir, '/root' on host, "mv /root/*.repo /etc/yum.repos.d" on host, "find /etc/yum.repos.d/ -name \"*.repo\" -exec sed -i \"s/baseurl\\s*=\\s*http:\\/\\/builds.puppetlabs.lan.*$/baseurl=file:\\/\\/\\/root\\/#{arch}/\" {} \\;" on host, "rpm -Uvh --force /root/*.rpm" when /^(debian|ubuntu)-([^-]+)-(.+)$/ variant = $1 version = $2 arch = $3 deb = fetch( "http://apt.puppetlabs.com/", "puppetlabs-release-%s.deb" % version, platform_configs_dir ) list = fetch( "http://builds.puppetlabs.lan/puppet/%s/repo_configs/deb/" % sha, "pl-puppet-%s-%s.list" % [sha, version], platform_configs_dir ) repo_dir = fetch_remote_dir("http://builds.puppetlabs.lan/puppet/%s/repos/apt/%s" % [sha, version], platform_configs_dir) on host, "rm -rf /root/*.list; rm -rf /root/*.deb; rm -rf /root/#{version}" scp_to host, deb, '/root' scp_to host, list, '/root' scp_to host, repo_dir, '/root' on host, "mv /root/*.list /etc/apt/sources.list.d" on host, "find /etc/apt/sources.list.d/ -name \"*.list\" -exec sed -i \"s/deb\\s\\+http:\\/\\/builds.puppetlabs.lan.*$/deb file:\\/\\/\\/root\\/#{version} #{version} main/\" {} \\;" on host, "dpkg -i --force-all /root/*.deb" on host, "apt-get update" else host.logger.notify("No repository installation step for #{platform} yet...") end end end end end diff --git a/acceptance/lib/puppet/acceptance/install_utils_spec.rb b/acceptance/lib/puppet/acceptance/install_utils_spec.rb index a124eef02..344a4e461 100644 --- a/acceptance/lib/puppet/acceptance/install_utils_spec.rb +++ b/acceptance/lib/puppet/acceptance/install_utils_spec.rb @@ -1,261 +1,261 @@ require File.join(File.dirname(__FILE__),'../../acceptance_spec_helper.rb') require 'puppet/acceptance/install_utils' describe 'InstallUtils' do class ATestCase include Puppet::Acceptance::InstallUtils end class Platform < String def with_version_codename self end end class TestHost attr_accessor :config def initialize(config = {}) self.config = config end def [](key) config[key] end end let(:host) { TestHost.new } let(:testcase) { ATestCase.new } describe "install_packages_on" do it "raises an error if package_hash has unknown platform keys" do expect do testcase.install_packages_on(host, { :foo => 'bar'}) end.to raise_error(RuntimeError, /Unknown platform 'foo' in package_hash/) end shared_examples_for(:install_packages_on) do |platform,command,package| let(:package_hash) do { :redhat => ['rh_package'], :debian => [['db_command', 'db_package']], } end let(:additional_switches) { platform == 'debian' ? '--allow-unauthenticated' : nil } before do logger = mock('logger', :notify => nil) host.stubs(:logger).returns(logger) host.config['platform'] = Platform.new(platform) end it "installs packages on a host" do host.expects(:check_for_package).never host.expects(:install_package).with(package, additional_switches).once testcase.install_packages_on(host, package_hash) end it "checks and installs packages on a host" do host.expects(:check_for_package).with(command).once host.expects(:install_package).with(package, additional_switches).once testcase.install_packages_on(host, package_hash, :check_if_exists => true) end end it_should_behave_like(:install_packages_on, 'fedora', 'rh_package', 'rh_package') it_should_behave_like(:install_packages_on, 'debian', 'db_command', 'db_package') end describe "fetch" do before do logger = stub('logger', :notify => nil) testcase.stubs(:logger).returns(logger) FileUtils.expects(:makedirs).with('dir') end it "does not fetch if destination file already exists" do File.expects(:exists?).with('dir/file').returns(true) testcase.expects(:open).never testcase.fetch('http://foo', 'file', 'dir') end it "fetches file from url and stores in destination directory as filename" do stream = mock('stream') file = mock('file') testcase.expects(:open).with('http://foo/file').yields(stream) File.expects(:open).with('dir/file', 'w').yields(file) FileUtils.expects(:copy_stream).with(stream, file) testcase.fetch('http://foo', 'file', 'dir') end it "returns path to destination file" do testcase.expects(:open).with('http://foo/file') expect(testcase.fetch('http://foo', 'file', 'dir')).to eql('dir/file') end end describe "fetch_remote_dir" do before do logger = stub('logger', {:notify => nil, :debug => nil}) testcase.stubs(:logger).returns(logger) end it "calls wget with the right amount of cut dirs for url that ends in '/'" do url = 'http://builds.puppetlabs.lan/puppet/7807591405af849da2ad6534c66bd2d4efff604f/repos/el/6/devel/x86_64/' testcase.expects(:`).with("wget -nv -P dir --reject \"index.html*\",\"*.gif\" --cut-dirs=6 -np -nH --no-check-certificate -r #{url} 2>&1").returns("log") expect( testcase.fetch_remote_dir(url, 'dir')).to eql('dir/x86_64') end it "calls wget with the right amount of cut dirs for url that doesn't end in '/'" do url = 'http://builds.puppetlabs.lan/puppet/7807591405af849da2ad6534c66bd2d4efff604f/repos/apt/wheezy' testcase.expects(:`).with("wget -nv -P dir --reject \"index.html*\",\"*.gif\" --cut-dirs=4 -np -nH --no-check-certificate -r #{url}/ 2>&1").returns("log") expect( testcase.fetch_remote_dir(url, 'dir')).to eql('dir/wheezy') end end shared_examples_for :redhat_platforms do |platform,sha,files| before do host.config['platform'] = Platform.new(platform) end it "fetches and installs repo configurations for #{platform}" do platform_configs_dir = "repo-configs/#{platform}" rpm_url = files[:rpm][0] rpm_file = files[:rpm][1] testcase.expects(:fetch).with( "http://yum.puppetlabs.com", rpm_file, platform_configs_dir ).returns("#{platform_configs_dir}/#{rpm_file}") repo_url = files[:repo][0] repo_file = files[:repo][1] testcase.expects(:fetch).with( repo_url, repo_file, platform_configs_dir ).returns("#{platform_configs_dir}/#{repo_file}") repo_dir_url = files[:repo_dir][0] repo_dir = files[:repo_dir][1] testcase.expects(:link_exists?).returns( true ) testcase.expects(:fetch_remote_dir).with( repo_dir_url, platform_configs_dir ).returns("#{platform_configs_dir}/#{repo_dir}") testcase.expects(:link_exists?).returns( true ) testcase.expects(:on).with(host, regexp_matches(/rm.*repo; rm.*rpm; rm.*#{repo_dir}/)) testcase.expects(:scp_to).with(host, "#{platform_configs_dir}/#{rpm_file}", '/root') testcase.expects(:scp_to).with(host, "#{platform_configs_dir}/#{repo_file}", '/root') testcase.expects(:scp_to).with(host, "#{platform_configs_dir}/#{repo_dir}", '/root') testcase.expects(:on).with(host, regexp_matches(%r{mv.*repo /etc/yum.repos.d})) testcase.expects(:on).with(host, regexp_matches(%r{find /etc/yum.repos.d/ -name .*})) testcase.expects(:on).with(host, regexp_matches(%r{rpm.*/root/.*rpm})) testcase.install_repos_on(host, sha, 'repo-configs') end end describe "install_repos_on" do let(:sha) { "abcdef10" } it_should_behave_like(:redhat_platforms, 'el-6-i386', 'abcdef10', { :rpm => [ "http://yum.puppetlabs.com", "puppetlabs-release-el-6.noarch.rpm", ], :repo => [ "http://builds.puppetlabs.lan/puppet/abcdef10/repo_configs/rpm/", "pl-puppet-abcdef10-el-6-i386.repo", ], :repo_dir => [ "http://builds.puppetlabs.lan/puppet/abcdef10/repos/el/6/products/i386/", "i386", ], }, ) it_should_behave_like(:redhat_platforms, - 'fedora-18-x86_64', + 'fedora-20-x86_64', 'abcdef10', { :rpm => [ "http://yum.puppetlabs.com", - "puppetlabs-release-fedora-18.noarch.rpm", + "puppetlabs-release-fedora-20.noarch.rpm", ], :repo => [ "http://builds.puppetlabs.lan/puppet/abcdef10/repo_configs/rpm/", - "pl-puppet-abcdef10-fedora-f18-x86_64.repo", + "pl-puppet-abcdef10-fedora-f20-x86_64.repo", ], :repo_dir => [ - "http://builds.puppetlabs.lan/puppet/abcdef10/repos/fedora/18/products/x86_64/", + "http://builds.puppetlabs.lan/puppet/abcdef10/repos/fedora/f20/products/x86_64/", "x86_64", ], }, ) it_should_behave_like(:redhat_platforms, 'centos-5-x86_64', 'abcdef10', { :rpm => [ "http://yum.puppetlabs.com", "puppetlabs-release-el-5.noarch.rpm", ], :repo => [ "http://builds.puppetlabs.lan/puppet/abcdef10/repo_configs/rpm/", "pl-puppet-abcdef10-el-5-x86_64.repo", ], :repo_dir => [ "http://builds.puppetlabs.lan/puppet/abcdef10/repos/el/5/products/x86_64/", "x86_64", ], }, ) it "installs on a debian host" do host.config['platform'] = platform = Platform.new('ubuntu-precise-x86_64') platform_configs_dir = "repo-configs/#{platform}" deb = "puppetlabs-release-precise.deb" testcase.expects(:fetch).with( "http://apt.puppetlabs.com/", deb, platform_configs_dir ).returns("#{platform_configs_dir}/#{deb}") list = "pl-puppet-#{sha}-precise.list" testcase.expects(:fetch).with( "http://builds.puppetlabs.lan/puppet/#{sha}/repo_configs/deb/", list, platform_configs_dir ).returns("#{platform_configs_dir}/#{list}") testcase.expects(:fetch_remote_dir).with( "http://builds.puppetlabs.lan/puppet/#{sha}/repos/apt/precise", platform_configs_dir ).returns("#{platform_configs_dir}/precise") testcase.expects(:on).with(host, regexp_matches(/rm.*list; rm.*deb; rm.*/)) testcase.expects(:scp_to).with(host, "#{platform_configs_dir}/#{deb}", '/root') testcase.expects(:scp_to).with(host, "#{platform_configs_dir}/#{list}", '/root') testcase.expects(:scp_to).with(host, "#{platform_configs_dir}/precise", '/root') testcase.expects(:on).with(host, regexp_matches(%r{mv.*list /etc/apt/sources.list.d})) testcase.expects(:on).with(host, regexp_matches(%r{find /etc/apt/sources.list.d/ -name .*})) testcase.expects(:on).with(host, regexp_matches(%r{dpkg -i.*/root/.*deb})) testcase.expects(:on).with(host, regexp_matches(%r{apt-get update})) testcase.install_repos_on(host, sha, 'repo-configs') end end end diff --git a/ext/debian/control b/ext/debian/control index 37f73025d..6f0e8467b 100644 --- a/ext/debian/control +++ b/ext/debian/control @@ -1,143 +1,143 @@ Source: puppet Section: admin Priority: optional Maintainer: Puppet Labs Uploaders: Micah Anderson , Andrew Pollock , Nigel Kersten , Stig Sandbeck Mathisen Build-Depends-Indep: ruby | ruby-interpreter, libopenssl-ruby | libopenssl-ruby1.9.1 | libruby (>= 1:1.9.3.4), facter (>= 1.7.0), hiera (>= 1.0.0) Build-Depends: debhelper (>= 7.0.0), openssl Standards-Version: 3.9.1 Vcs-Git: git://github.com/puppetlabs/puppet Homepage: http://projects.puppetlabs.com/projects/puppet Package: puppet-common Architecture: all Depends: ${misc:Depends}, ruby | ruby-interpreter, libopenssl-ruby | libopenssl-ruby1.9.1 | libruby (>= 1:1.9.3.4), ruby-shadow | libshadow-ruby1.8, libaugeas-ruby | libaugeas-ruby1.9.1 | libaugeas-ruby1.8, adduser, lsb-base, sysv-rc (>= 2.86) | file-rc, hiera (>= 1.0.0), facter (>= 1.7.0), ruby-rgen (>= 0.6.5), libjson-ruby | ruby-json Recommends: lsb-release, debconf-utils Suggests: ruby-selinux | libselinux-ruby1.8, librrd-ruby1.9.1 | librrd-ruby1.8 Breaks: puppet (<< 2.6.0~rc2-1), puppetmaster (<< 0.25.4-1) Provides: hiera-puppet Conflicts: hiera-puppet Replaces: hiera-puppet Description: Centralized configuration management Puppet lets you centrally manage every important aspect of your system using a cross-platform specification language that manages all the separate elements normally aggregated in different files, like users, cron jobs, and hosts, along with obviously discrete elements like packages, services, and files. . Puppet's simple declarative specification language provides powerful classing abilities for drawing out the similarities between hosts while allowing them to be as specific as necessary, and it handles dependency and prerequisite relationships between objects clearly and explicitly. . This package contains the puppet software and documentation. For the startup scripts needed to run the puppet agent and master, see the "puppet" and "puppetmaster" packages, respectively. Package: puppet Architecture: all Depends: ${misc:Depends}, puppet-common (= ${binary:Version}), ruby | ruby-interpreter Recommends: rdoc Suggests: puppet-el, vim-puppet Description: Centralized configuration management - agent startup and compatibility scripts This package contains the startup script and compatbility scripts for the puppet agent, which is the process responsible for configuring the local node. . Puppet lets you centrally manage every important aspect of your system using a cross-platform specification language that manages all the separate elements normally aggregated in different files, like users, cron jobs, and hosts, along with obviously discrete elements like packages, services, and files. . Puppet's simple declarative specification language provides powerful classing abilities for drawing out the similarities between hosts while allowing them to be as specific as necessary, and it handles dependency and prerequisite relationships between objects clearly and explicitly. Package: puppetmaster-common Architecture: all Depends: ${misc:Depends}, ruby | ruby-interpreter, puppet-common (= ${binary:Version}), facter (>= 1.7.0), lsb-base Breaks: puppet (<< 0.24.7-1), puppetmaster (<< 2.6.1~rc2-1) Replaces: puppetmaster (<< 2.6.1~rc2-1) Suggests: apache2 | nginx, puppet-el, vim-puppet, stompserver, ruby-stomp | libstomp-ruby1.8, rdoc, ruby-ldap | libldap-ruby1.8, puppetdb-terminus Description: Puppet master common scripts This package contains common scripts for the puppet master, which is the server hosting manifests and files for the puppet nodes. . Puppet lets you centrally manage every important aspect of your system using a cross-platform specification language that manages all the separate elements normally aggregated in different files, like users, cron jobs, and hosts, along with obviously discrete elements like packages, services, and files. . Puppet's simple declarative specification language provides powerful classing abilities for drawing out the similarities between hosts while allowing them to be as specific as necessary, and it handles dependency and prerequisite relationships between objects clearly and explicitly. Package: puppetmaster Architecture: all Depends: ${misc:Depends}, ruby | ruby-interpreter, puppetmaster-common (= ${source:Version}), facter (>= 1.7.0), lsb-base Breaks: puppet (<< 0.24.7-1) Suggests: apache2 | nginx, puppet-el, vim-puppet, stompserver, ruby-stomp | libstomp-ruby1.8, rdoc, ruby-ldap | libldap-ruby1.8, puppetdb-terminus Description: Centralized configuration management - master startup and compatibility scripts This package contains the startup and compatibility scripts for the puppet master, which is the server hosting manifests and files for the puppet nodes. . Puppet lets you centrally manage every important aspect of your system using a cross-platform specification language that manages all the separate elements normally aggregated in different files, like users, cron jobs, and hosts, along with obviously discrete elements like packages, services, and files. . Puppet's simple declarative specification language provides powerful classing abilities for drawing out the similarities between hosts while allowing them to be as specific as necessary, and it handles dependency and prerequisite relationships between objects clearly and explicitly. Package: puppetmaster-passenger Architecture: all -Depends: ${misc:Depends}, ruby | ruby-interpreter, puppetmaster-common (= ${source:Version}), facter (>= 1.7.0), lsb-base, libapache2-mod-passenger +Depends: ${misc:Depends}, ruby | ruby-interpreter, puppetmaster-common (= ${source:Version}), facter (>= 1.7.0), lsb-base, apache2, libapache2-mod-passenger Conflicts: puppetmaster (<< 2.6.1~rc2-1) Replaces: puppetmaster (<< 2.6.1~rc2-1) Description: Centralised configuration management - master setup to run under mod passenger This package provides a puppetmaster running under mod passenger. This configuration offers better performance and scalability. . Puppet lets you centrally manage every important aspect of your system using a cross-platform specification language that manages all the separate elements normally aggregated in different files, like users, cron jobs, and hosts, along with obviously discrete elements like packages, services, and files. . Puppet's simple declarative specification language provides powerful classing abilities for drawing out the similarities between hosts while allowing them to be as specific as necessary, and it handles dependency and prerequisite relationships between objects clearly and explicitly. . Package: vim-puppet Architecture: all Depends: ${misc:Depends} Recommends: vim-addon-manager Conflicts: puppet (<< ${source:Version}) Description: syntax highlighting for puppet manifests in vim The vim-puppet package provides filetype detection and syntax highlighting for puppet manifests (files ending with ".pp"). Package: puppet-el Architecture: all Depends: ${misc:Depends}, emacsen-common Conflicts: puppet (<< ${source:Version}) Description: syntax highlighting for puppet manifests in emacs The puppet-el package provides syntax highlighting for puppet manifests Package: puppet-testsuite Architecture: all Depends: ${misc:Depends}, ruby | ruby-interpreter, puppet-common (= ${source:Version}), facter (>= 1.7.0), lsb-base, rails (>= 1.2.3-2), rdoc, ruby-ldap | libldap-ruby1.8, ruby-rspec | librspec-ruby, git-core, ruby-mocha | libmocha-ruby1.8 Recommends: cron Description: Centralized configuration management - test suite This package provides all the tests from the upstream puppet source code. The tests are used for improving the QA of the puppet package. diff --git a/ext/debian/puppetmaster-passenger.postinst b/ext/debian/puppetmaster-passenger.postinst index 019063be4..2c9f20c3f 100644 --- a/ext/debian/puppetmaster-passenger.postinst +++ b/ext/debian/puppetmaster-passenger.postinst @@ -1,66 +1,112 @@ #!/bin/sh set -e +sitename="puppetmaster" + +# The debian provided a2* utils in Apache 2.4 uses "site name" as +# argument, while the version in Apache 2.2 uses "file name". +# +# For added fun, the Apache 2.4 version requires files to have a +# ".conf" suffix, but this must be stripped when using it as argument +# for the a2* utilities. +# +# This will end in tears… +# Can be removed when we only support apache >= 2.4 +apache2_puppetmaster_sitename() { + apache2_version="$(dpkg-query --showformat='${Version}\n' --show apache2)" + if dpkg --compare-versions "$apache2_version" gt "2.4~"; then + echo "${sitename}.conf" + else + echo "${sitename}" + fi +} + +# Can be removed when we only support apache >= 2.4 +restart_apache2() { + if [ -x "/etc/init.d/apache2" ]; then + # Seems that a restart is needed. reload breaks ssl apparently. + if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then + invoke-rc.d apache2 restart || exit $? + else + /etc/init.d/apache2 restart || exit $? + fi + fi +} + +# We may need to update the passenger directives in the apache vhost because +# RailsAutoDetect and RackAutoDetect were removed in passenger 4.0.0 +# see http://www.modrails.com/documentation/Users%20guide%20Apache.html#_railsautodetect_rackautodetect_and_wsgiautodetect +update_vhost_for_passenger4() { + # Get passenger version from dpkg. + # This will end in tears… + passenger_version="$(dpkg-query --showformat='${Version}\n' --show libapache2-mod-passenger)" + if dpkg --compare-versions "$passenger_version" gt "4.0~"; then + sed -r -i \ + -e "/RailsAutoDetect/d" \ + -e "/RackAutoDetect/d" \ + $tempfile + fi +} + if [ "$1" = "configure" ]; then - + # Change the owner of the rack config.ru to be the puppet user # because passenger will suid to that user, see #577366 if ! dpkg-statoverride --list /usr/share/puppet/rack/puppetmasterd/config.ru >/dev/null 2>&1 then - dpkg-statoverride --update --add puppet puppet 0644 /usr/share/puppet/rack/puppetmasterd/config.ru + dpkg-statoverride --update --add puppet puppet 0644 /usr/share/puppet/rack/puppetmasterd/config.ru fi # Setup passenger configuration if [ "$2" = "" ]; then - # Initialize puppetmaster CA and generate the master certificate + + # Check that puppet master --configprint works properly + # If it doesn't the following steps to update the vhost will produce a very unhelpful and broken vhost + if [ $(puppet master --configprint all 2>&1 | grep "Could not parse" | wc -l) != "0" ]; then + echo "Puppet config print not working properly, exiting" + exit 1 + fi + + # Initialize puppetmaster CA and generate the master certificate # only if the host doesn't already have any puppet ssl certificate. # The ssl key and cert need to be available (eg generated) before - # apache2 is configured and started since apache2 ssl configuration + # apache2 is configured and started since apache2 ssl configuration # uses the puppetmaster ssl files. - if [ ! -e "$(puppet master --configprint hostcert)" ]; then - puppet cert generate $(puppet master --configprint certname) - fi + if [ ! -e "$(puppet master --configprint hostcert)" ]; then + puppet cert generate $(puppet master --configprint certname) + fi + # Setup apache2 configuration files - APACHE2_SITE_FILE="/etc/apache2/sites-available/puppetmaster" + APACHE2_SITE_FILE="/etc/apache2/sites-available/$(apache2_puppetmaster_sitename)" if [ ! -e "${APACHE2_SITE_FILE}" ]; then - cp /usr/share/puppetmaster-passenger/apache2.site.conf.tmpl "${APACHE2_SITE_FILE}" - # Fix path to SSL files - sed -r -i "s|(SSLCertificateFile\s+).+$|\1$(puppet master --configprint hostcert)|" "${APACHE2_SITE_FILE}" - sed -r -i "s|(SSLCertificateKeyFile\s+).+$|\1$(puppet master --configprint hostprivkey)|" "${APACHE2_SITE_FILE}" - sed -r -i "s|(SSLCACertificateFile\s+).+$|\1$(puppet master --configprint localcacert)|" "${APACHE2_SITE_FILE}" - sed -r -i "s|(SSLCertificateChainFile\s+).+$|\1$(puppet master --configprint localcacert)|" "${APACHE2_SITE_FILE}" - sed -r -i "s|(SSLCARevocationFile\s+).+$|\1$(puppet master --configprint cacrl)|" "${APACHE2_SITE_FILE}" - - # Fix path to rack docroot and directory - sed -r -i "s|DocumentRoot /etc/puppet/rack/public|DocumentRoot /usr/share/puppet/rack/puppetmasterd/public|g" "${APACHE2_SITE_FILE}" - sed -r -i "s|||g" "${APACHE2_SITE_FILE}" + tempfile=$(mktemp) + sed -r \ + -e "s|(SSLCertificateFile\s+).+$|\1$(puppet master --configprint hostcert)|" \ + -e "s|(SSLCertificateKeyFile\s+).+$|\1$(puppet master --configprint hostprivkey)|" \ + -e "s|(SSLCACertificateFile\s+).+$|\1$(puppet master --configprint localcacert)|" \ + -e "s|(SSLCertificateChainFile\s+).+$|\1$(puppet master --configprint localcacert)|" \ + -e "s|(SSLCARevocationFile\s+).+$|\1$(puppet master --configprint cacrl)|" \ + -e "s|DocumentRoot /etc/puppet/rack/public|DocumentRoot /usr/share/puppet/rack/puppetmasterd/public|" \ + -e "s|||" \ + /usr/share/puppetmaster-passenger/apache2.site.conf.tmpl > $tempfile + update_vhost_for_passenger4 + mv $tempfile "${APACHE2_SITE_FILE}" fi + + # Enable needed modules a2enmod ssl a2enmod headers - a2ensite puppetmaster - if [ -x "/etc/init.d/apache2" ]; then - # Seems that a restart is needed. reload breaks ssl apparently. - if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then - invoke-rc.d apache2 restart || exit $? - else - /etc/init.d/apache2 restart || exit $? - fi - fi + a2ensite ${sitename} + restart_apache2 fi + # Fix CRL file on upgrade to use the CA crl file instead of the host crl. if dpkg --compare-versions "$2" lt-nl "2.6.1-1"; then if [ -e /etc/apache2/sites-available/puppetmaster ]; then sed -r -i 's|SSLCARevocationFile[[:space:]]+/var/lib/puppet/ssl/crl.pem$|SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem|' /etc/apache2/sites-available/puppetmaster - if [ -x "/etc/init.d/apache2" ]; then - # Seems that a restart is needed. reload breaks ssl apparently. - if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then - invoke-rc.d apache2 restart || exit $? - else - /etc/init.d/apache2 restart || exit $? - fi - fi + restart_apache2 fi fi fi #DEBHELPER# diff --git a/ext/debian/puppetmaster-passenger.postrm b/ext/debian/puppetmaster-passenger.postrm index a7f34b61e..ec86b5de1 100644 --- a/ext/debian/puppetmaster-passenger.postrm +++ b/ext/debian/puppetmaster-passenger.postrm @@ -1,33 +1,61 @@ -#!/bin/sh -e +#!/bin/sh + +set -e + +sitename="puppetmaster" + +# The debian provided a2* utils in Apache 2.4 uses "site name" as +# argument, while the version in Apache 2.2 uses "file name". +# +# For added fun, the Apache 2.4 version requires files to have a +# ".conf" suffix, but this must be stripped when using it as argument +# for the a2* utilities. +# +# This will end in tears… +# Can be removed when we only support apache >= 2.4 +apache2_puppetmaster_sitename() { + apache2_version="$(dpkg-query --showformat='${Version}\n' --show apache2)" + if dpkg --compare-versions "$apache2_version" gt "2.4~"; then + echo "${sitename}.conf" + else + echo "${sitename}" + fi +} + +# Can be removed when we only support apache >= 2.4 +restart_apache2() { + if [ -x "/etc/init.d/apache2" ]; then + # Seems that a restart is needed. reload breaks ssl apparently. + if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then + invoke-rc.d apache2 restart || exit $? + else + /etc/init.d/apache2 restart || exit $? + fi + fi +} case "$1" in purge) - if dpkg-statoverride --list /usr/share/puppet/rack/puppetmasterd/config.ru >/dev/null 2>&1 - then - dpkg-statoverride --remove /usr/share/puppet/rack/puppetmasterd/config.ru - fi - # Remove the puppetmaster site configuration on purge - rm -f /etc/apache2/sites-available/puppetmaster - ;; + if dpkg-statoverride --list /usr/share/puppet/rack/puppetmasterd/config.ru >/dev/null 2>&1 + then + dpkg-statoverride --remove /usr/share/puppet/rack/puppetmasterd/config.ru + fi + # Remove the puppetmaster site configuration on purge + rm -f /etc/apache2/sites-available/$(apache2_puppetmaster_sitename) + ;; remove) # Disable the puppetmaster apache2 site configuration on package removal - a2dissite puppetmaster - if [ -x "/etc/init.d/apache2" ]; then - if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then - invoke-rc.d apache2 force-reload || exit $? - else - /etc/init.d/apache2 force-reload || exit $? - fi - fi - ;; + a2dissite ${sitename} + restart_apache2 + ;; upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 esac #DEBHELPER# exit 0