diff --git a/manifests/extension/config.pp b/manifests/extension/config.pp index 3a7378b..0df7f3b 100644 --- a/manifests/extension/config.pp +++ b/manifests/extension/config.pp @@ -1,136 +1,138 @@ # Configure a PHP extension package # # === Parameters # # [*ensure*] # The ensure of the package to install # Could be "latest", "installed" or a pinned version # # [*provider*] # The provider used to install the package # Could be "pecl", "apt", "dpkg" or any other OS package provider # If set to "none", no package will be installed # # [*so_name*] # The DSO name of the package (e.g. opcache for zendopcache) # # [*ini_prefix*] # An optional filename prefix for the settings file of the extension # # [*php_api_version*] # This parameter is used to build the full path to the extension # directory for zend_extension in PHP < 5.5 (e.g. 20100525) # # [*header_packages*] # System packages dependencies to install for extensions (e.g. for # memcached libmemcached-dev on Debian) # # [*compiler_packages*] # System packages dependencies to install for compiling extensions # (e.g. build-essential on Debian) # # [*zend*] # Boolean parameter, whether to load extension as zend_extension. # Defaults to false. # # [*settings*] # Nested hash of global config parameters for php.ini # # [*settings_prefix*] # Boolean/String parameter, whether to prefix all setting keys with # the extension name or specified name. Defaults to false. # # [*sapi*] # String parameter, whether to specify ALL sapi or a specific sapi. # Defaults to ALL. # define php::extension::config ( String $ensure = 'installed', Optional[Php::Provider] $provider = undef, Optional[String] $so_name = downcase($name), Optional[String] $ini_prefix = undef, Optional[String] $php_api_version = undef, Boolean $zend = false, Hash $settings = {}, Variant[Boolean, String] $settings_prefix = false, Php::Sapi $sapi = 'ALL', ) { if ! defined(Class['php']) { warning('php::extension::config is private') } if $zend == true { $extension_key = 'zend_extension' $module_path = $php_api_version? { undef => undef, default => "/usr/lib/php5/${php_api_version}/", } } else { $extension_key = 'extension' $module_path = undef } $ini_name = downcase($so_name) # Ensure "." prefix is present in setting keys if requested $full_settings = $settings_prefix? { true => ensure_prefix($settings, "${so_name}."), false => $settings, String => ensure_prefix($settings, "${settings_prefix}."), } if $provider != 'pear' { $final_settings = deep_merge( {"${extension_key}" => "${module_path}${so_name}.so"}, $full_settings ) } else { $final_settings = $full_settings } if $facts['os']['name'] == 'Ubuntu' and $zend != true and $name == 'mysql' { # Do not manage the .ini file if it's mysql. PHP 7.0+ do not have # mysql.so. If mysql.ini exists and version is 7.0+, then remove it. $real_ensure = 'absent' } else { $real_ensure = $ensure } $config_root_ini = pick_default($php::config_root_ini, $php::params::config_root_ini) if $real_ensure != 'absent' { ::php::config { $title: file => "${config_root_ini}/${ini_prefix}${ini_name}.ini", config => $final_settings, } # Ubuntu/Debian systems use the mods-available folder. We need to enable # settings files ourselves with php5enmod command. $ext_tool_enable = pick_default($php::ext_tool_enable, $php::params::ext_tool_enable) $ext_tool_query = pick_default($php::ext_tool_query, $php::params::ext_tool_query) $ext_tool_enabled = pick_default($php::ext_tool_enabled, $php::params::ext_tool_enabled) if $facts['os']['family'] == 'Debian' and $ext_tool_enabled { $cmd = "${ext_tool_enable} -s ${sapi} ${so_name}" + $execname = "ext_tool_enable_${so_name}" $_sapi = $sapi? { 'ALL' => 'cli', default => $sapi, } - if has_key($final_settings, 'extension') and $final_settings[extension] { - exec { $cmd: + if has_key($final_settings, $extension_key) and $final_settings[$extension_key] { + exec { $execname: + command => $cmd, onlyif => "${ext_tool_query} -s ${_sapi} -m ${so_name} | /bin/grep 'No module matches ${so_name}'", require => ::Php::Config[$title], } if $php::fpm { - Package[$php::fpm::package] ~> Exec[$cmd] + Package[$php::fpm::package] ~> Exec[$execname] } } } } else { file {"${config_root_ini}/${ini_prefix}${ini_name}.ini": ensure => 'absent', } } } diff --git a/spec/defines/extension_spec.rb b/spec/defines/extension_spec.rb index 812fa03..66c2e85 100644 --- a/spec/defines/extension_spec.rb +++ b/spec/defines/extension_spec.rb @@ -1,247 +1,262 @@ require 'spec_helper' describe 'php::extension' do on_supported_os.each do |os, facts| context "on #{os}" do let :facts do facts end let(:pre_condition) { 'include php' } unless facts[:osfamily] == 'Suse' || facts[:osfamily] == 'FreeBSD' # FIXME: something is wrong on these etcdir = case facts[:os]['name'] when 'Debian' case facts[:os]['release']['major'] when '10' '/etc/php/7.3/mods-available' when '9' '/etc/php/7.0/mods-available' else '/etc/php5/mods-available' end when 'Ubuntu' case facts[:os]['release']['major'] when '18.04' '/etc/php/7.2/mods-available' when '16.04' '/etc/php/7.0/mods-available' else '/etc/php5/mods-available' end when 'Archlinux' '/etc/php/conf.d' else '/etc/php.d' end context 'installation from repository' do let(:title) { 'json' } let(:params) do { package_prefix: 'php5-', settings: { 'test' => 'foo' } } end it { is_expected.to contain_package('php5-json') } it do is_expected.to contain_php__config('json').with( file: "#{etcdir}/json.ini", config: { 'extension' => 'json.so', 'test' => 'foo' } ) end end context 'configure extension without installing a package' do let(:title) { 'json' } let(:params) do { provider: 'none', settings: { 'test' => 'foo' } } end it do is_expected.to contain_php__config('json').with( file: "#{etcdir}/json.ini", require: nil, config: { 'extension' => 'json.so', 'test' => 'foo' } ) end end context 'add settings prefix if requested' do let(:title) { 'json' } let(:params) do { name: 'json', settings_prefix: true, settings: { 'test' => 'foo' } } end it do is_expected.to contain_php__config('json').with( config: { 'extension' => 'json.so', 'json.test' => 'foo' } ) end end context 'use specific settings prefix if requested' do let(:title) { 'json' } let(:params) do { name: 'json', settings_prefix: 'bar', settings: { 'test' => 'foo' } } end it do is_expected.to contain_php__config('json').with( config: { 'extension' => 'json.so', 'bar.test' => 'foo' } ) end end context 'extensions can be configured as zend' do let(:title) { 'xdebug' } let(:params) do { zend: true } end it { is_expected.to contain_php__config('xdebug').with_config('zend_extension' => 'xdebug.so') } end context 'pecl extensions support so_name' do let(:title) { 'zendopcache' } let(:params) do { provider: 'pecl', zend: true, so_name: 'opcache' } end it do is_expected.to contain_php__config('zendopcache').with( file: "#{etcdir}/opcache.ini", config: { 'zend_extension' => 'opcache.so' } ) end end context 'add ini file prefix if requested' do let(:title) { 'zendopcache' } let(:params) do { provider: 'pecl', zend: true, ini_prefix: '10-', so_name: 'opcache' } end it do is_expected.to contain_php__config('zendopcache').with( file: "#{etcdir}/10-opcache.ini", config: { 'zend_extension' => 'opcache.so' } ) end end context 'pecl extensions support php_api_version' do let(:title) { 'xdebug' } let(:params) do { provider: 'pecl', zend: true, php_api_version: '20100525' } end it { is_expected.to contain_php__config('xdebug').with_config('zend_extension' => '/usr/lib/php5/20100525/xdebug.so') } end + if facts[:os]['family'] == 'Debian' + context 'on Debian family' do + context 'zend extensions call ext_tool_enable' do + let(:title) { 'xdebug' } + let(:params) do + { + zend: true + } + end + + it { is_expected.to contain_exec('ext_tool_enable_xdebug') } + end + end + end + case facts[:os]['name'] when 'Debian' context 'on Debian' do let(:title) { 'xdebug' } it { is_expected.to contain_php__config('xdebug').with_file("#{etcdir}/xdebug.ini") } # note to consider: As of PHP 5.2.0, the JSON extension is bundled and compiled into PHP by default # http://php.net/manual/en/json.installation.php context 'pecl installation' do let(:title) { 'json' } let(:params) do { provider: 'pecl', header_packages: ['libmemcached-dev'], name: 'nice_name', settings: { 'test' => 'foo' } } end it { is_expected.to contain_package('json') } it { is_expected.to contain_package('libmemcached-dev') } it { is_expected.to contain_package('build-essential') } it do is_expected.to contain_php__config('json').with( file: "#{etcdir}/nice_name.ini", config: { 'extension' => 'nice_name.so', 'test' => 'foo' } ) end end end when 'Ubuntu' context 'on Ubuntu' do context 'do not setup mysql.ini' do let(:title) { 'mysql' } let(:params) do { name: 'mysql' } end it do is_expected.to contain_file("#{etcdir}/mysql.ini").with(ensure: 'absent') end end end end end end end end