puppet-php icon indicating copy to clipboard operation
puppet-php copied to clipboard

Php extensions refreshing in every run in Debian.

Open guzmanbraso opened this issue 8 years ago • 11 comments
trafficstars

Affected Puppet, Ruby, OS and module versions/distributions

  • Puppet: 5.2.0
  • Ruby: ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu]
  • Distribution: Debian 9 (Stretch)
  • Module version: master branch.

How to reproduce (e.g Puppet code you use)

Call inside our module init.pp:

  class { '::php::globals':
    php_version => $version,
    config_root => "/etc/php/$version",
  } ->
  class { '::php':
    ensure           => "${version}*",
    manage_repos     => $manage_repos,
    fpm              => $fpm,
    fpm_service_name => $fpm_service_name,
    dev              => $dev,
    composer         => $composer,
    pear             => $pear,
    phpunit          => $phpunit,
    settings         => $merged_settings,
    package_prefix   => $package_prefix,
    extensions       => $extensions,
    ext_tool_enable  => $ext_tool_enable,
    ext_tool_query   => $ext_tool_query
  }

Our module params inherited:

  # General params for php
  $version          = '5.6'
  $settings         = {
    'Date/date.timezone'                      => 'utc',
    'PHP/display_errors'                      => 'Off',
    'PHP/log_errors'                          => 'On',
    'PHP/error_log'                           => "/var/log/php/${version}-phpini.error.log",
    'PHP/memory_limit'                        => '256M',
    'PHP/cgi.fix_pathinfo'                    => 0,
    'opcache/opcache.enable'                  => 1,
    'opcache/opcache.memory_consumption'      => '256',
    'opcache/opcache.interned_strings_buffer' => '32',
    'opcache/opcache.max_accelerated_files'   => '10000',
    'opcache/opcache.use_cwd'                 => 1,
    'opcache/opcache.validate_timestamps'     => 0,
    'opcache/opcache.fast_shutdown'           => 1,
    'opcache/opcache.error_log'               => "/var/log/php/${version}/opcache.error.log",
    'opcache/opcache.log_verbosity_level'     => '2',
    'PHP/realpath_cache_size'                 => '1024k',
    'PHP/realpath_cache_ttl'                  => '300'
  }
  $fpm              = true 
  $fpm_service_name = "php${version}-fpm"
  $manage_repos     = false
  $dev              = true
  $composer         = false
  $pear             = false
  $phpunit          = false
  $logdir           = '/var/log/php'
  $package_prefix   = "php${version}-"
  $user             = 'phpuser'
  $userid           = undef
  $group            = 'phpgroup'
  $groupid          = undef
  $listen           = '127.0.0.1:9000'
  $memory_limit     = '128M'
  $extensions = {
    curl => {
      provider        => 'apt',
      package_prefix  => "php${version}-",
    },
    gd => {
      provider => 'apt',
      package_prefix  => "php${version}-",
    },
    imagick => {
      provider => 'apt',
      package_prefix  => "php${version}-",
    },
    mcrypt => {
      provider => 'apt',
      package_prefix  => "php${version}-",
    },
    mysql => {
      provider => 'apt',
      package_prefix  => "php${version}-",
    },
    redis => {
      provider => 'apt',
      package_prefix  => "php${version}-",
    }
  }
  $ext_tool_enable         = "/usr/sbin/phpenmod -v ${version}"
  $ext_tool_query          = "/usr/sbin/phpquery -v ${version}"
  $pm                      = 'dynamic'
  $pm_max_children         = '5'
  $pm_start_servers        = '2'
  $pm_min_spare_servers    = '1'
  $pm_max_spare_servers    = '3'
  $pm_max_requests         = '0'
  $pm_process_idle_timeout = '10s'
  $pm_status_path          = '/fpm-status'
  $php_value               = {}
  $php_flag                = {}
  $php_admin_value         = {}
  $php_admin_flag          = {}
  $php_directives          = []

What are you seeing

In every run puppet tries to enable the module again when it was already installed and enabled by puppet.

What behaviour did you expect instead

A clean run, as the modules were already installed by puppet, already enabled and checking through phpinfo() I see all modules are working ok in fpm.

Output log

Info: /Stage[main]/Php::Fpm/Package[php5.6-fpm]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 5.6 -s fpm curl]
Info: /Stage[main]/Php::Fpm/Package[php5.6-fpm]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 5.6 -s fpm gd]
Info: /Stage[main]/Php::Fpm/Package[php5.6-fpm]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 5.6 -s fpm imagick]
Info: /Stage[main]/Php::Fpm/Package[php5.6-fpm]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 5.6 -s fpm mcrypt]
Info: /Stage[main]/Php::Fpm/Package[php5.6-fpm]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 5.6 -s fpm mysql]
Info: /Stage[main]/Php::Fpm/Package[php5.6-fpm]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 5.6 -s fpm redis]
Notice: /Stage[main]/Php/Php::Extension[imagick]/Php::Extension::Install[imagick]/Package[php5.6-imagick]/ensure: created
Info: Php::Extension::Install[imagick]: Scheduling refresh of Php::Extension::Config[imagick]
Info: Php::Extension::Config[imagick]: Scheduling refresh of Php::Config[imagick]
Info: Php::Extension::Config[imagick]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 5.6 -s fpm imagick]
Info: Php::Config[imagick]: Scheduling refresh of Php::Config::Setting[/etc/php/5.6/mods-available/imagick.ini: extension]
Notice: /Stage[main]/Php/Php::Extension[redis]/Php::Extension::Install[redis]/Package[php5.6-redis]/ensure: created
Info: Php::Extension::Install[redis]: Scheduling refresh of Php::Extension::Config[redis]
Info: Php::Extension::Config[redis]: Scheduling refresh of Php::Config[redis]
Info: Php::Extension::Config[redis]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 5.6 -s fpm redis]
Info: Php::Config[redis]: Scheduling refresh of Php::Config::Setting[/etc/php/5.6/mods-available/redis.ini: extension]
Info: Php::Config::Setting[/etc/php/5.6/mods-available/imagick.ini: extension]: Scheduling refresh of Ini_setting[/etc/php/5.6/mods-available/imagick.ini: extension]
Info: Php::Config::Setting[/etc/php/5.6/mods-available/redis.ini: extension]: Scheduling refresh of Ini_setting[/etc/php/5.6/mods-available/redis.ini: extension]
Notice: /Stage[main]/Php/Php::Extension[curl]/Php::Extension::Config[curl]/Exec[/usr/sbin/phpenmod -v 5.6 -s fpm curl]: Triggered 'refresh' from 1 event
Info: Php::Extension[curl]: Scheduling refresh of Service[php5.6-fpm]
Notice: /Stage[main]/Php/Php::Extension[gd]/Php::Extension::Config[gd]/Exec[/usr/sbin/phpenmod -v 5.6 -s fpm gd]: Triggered 'refresh' from 1 event
Info: Php::Extension[gd]: Scheduling refresh of Service[php5.6-fpm]
Notice: /Stage[main]/Php/Php::Extension[imagick]/Php::Extension::Config[imagick]/Php::Config[imagick]/Php::Config::Setting[/etc/php/5.6/mods-available/imagick.ini: extension]/Ini_setting[/etc/php/5.6/mods-available/imagick.ini: extension]: Triggered 'refresh' from 1 event
Notice: /Stage[main]/Php/Php::Extension[imagick]/Php::Extension::Config[imagick]/Exec[/usr/sbin/phpenmod -v 5.6 -s fpm imagick]: Triggered 'refresh' from 2 events
Info: Php::Extension[imagick]: Scheduling refresh of Service[php5.6-fpm]
Notice: /Stage[main]/Php/Php::Extension[mcrypt]/Php::Extension::Config[mcrypt]/Exec[/usr/sbin/phpenmod -v 5.6 -s fpm mcrypt]: Triggered 'refresh' from 1 event
Info: Php::Extension[mcrypt]: Scheduling refresh of Service[php5.6-fpm]
Notice: /Stage[main]/Php/Php::Extension[mysql]/Php::Extension::Config[mysql]/Exec[/usr/sbin/phpenmod -v 5.6 -s fpm mysql]: Triggered 'refresh' from 1 event
Info: Php::Extension[mysql]: Scheduling refresh of Service[php5.6-fpm]
Notice: /Stage[main]/Php/Php::Extension[redis]/Php::Extension::Config[redis]/Php::Config[redis]/Php::Config::Setting[/etc/php/5.6/mods-available/redis.ini: extension]/Ini_setting[/etc/php/5.6/mods-available/redis.ini: extension]: Triggered 'refresh' from 1 event
Notice: /Stage[main]/Php/Php::Extension[redis]/Php::Extension::Config[redis]/Exec[/usr/sbin/phpenmod -v 5.6 -s fpm redis]: Triggered 'refresh' from 2 events
Info: Php::Extension[redis]: Scheduling refresh of Service[php5.6-fpm]
Notice: /Stage[main]/Php::Fpm::Service/Service[php5.6-fpm]: Triggered 'refresh' from 6 events

Any additional information you'd like to impart

I saw there is an ifonly in the exec that enable modules:

      onlyif  => "${ext_tool_query} -s ${_sapi} -m ${so_name} | /bin/grep 'No module matches ${so_name}'",

And if I place a notify attached to the exec to output the precise command that was run and then execute it myself it works as expected:

root@testing:~# phpquery -v 5.6 -s cli -m redis
redis (Enabled for cli by maintainer script)

Even with the grep the exit status code seems right:

root@testing:~# phpquery -v 5.6 -s cli -m redis |grep 'No module matches redis'
root@testing:~# echo $?
1

However, puppet keeps trying to enable the module even when phpquery says it's enabled.

I'm willing to help if someone points me to where to continue debugging, it's really annoying to have to restart fpm in every puppet run.

Thank you all!

guzmanbraso avatar Sep 28 '17 21:09 guzmanbraso

Anyone? It's really annoying to won't be able to have clean runs in any node using this module.

guzmanbraso avatar Nov 13 '17 16:11 guzmanbraso

Hello, I have same issue here :-\

Puppet keeps trying to install the extensions/module even when it' installed, but only extensions from PECL. I tested with extensions imagick and memcached from PECL.

I am debugging for more information, maybe the puppet package (file manifest/extensions/install.pp line start with package { $real_package ) is the problem. Puppet package keep try to install extension because it not detect that extension/module is alread installed.

But I not sure about it.

leoserra avatar Dec 10 '17 16:12 leoserra

same here. i have not fully tracked it down, but i am sure it is because of debian9 has a different extensions compiled its core. so they are not available as standalone extension.

c33s avatar Dec 10 '17 17:12 c33s

puppet: 4.10.0 debian: stretch module: forge -> 5.1.0

i silenced the php module by using this hiera:

php::extensions:
  bcmath: {}
  bz2: {}
  curl: {}
  dba: {}
  gd: {}
  igbinary: { package_prefix: 'php-' } ###
  imagick: { package_prefix: 'php-' } ###
  imap: {}
  intl: {}
  ldap: {}
  mbstring: {}
  mcrypt: {}
  memcached: { package_prefix: 'php-' } ###
  msgpack: { package_prefix: 'php-' } ###
  mysql: {} ###
  soap: {}
  sqlite3: {}
  xml: {}
  xsl: {}
  zip: {}

for example imagick ist not available as php7.0-imagick only as php-imagick, i have to provide a custom package prefix for this module.

https://packages.debian.org/stretch/php-imagick https://packages.debian.org/search?suite=all&section=all&arch=any&searchon=names&keywords=php7.0-imagick

c33s avatar Dec 10 '17 21:12 c33s

It seems only a problem if you provide a concrete version:

This works only once:

'mcrypt'   => {
                                provider        => 'pecl',
                                ensure          => '1.0.1',
                                header_packages => [ 'libmcrypt-dev', ],
},

This works then:

'mcrypt'   => {
                                provider        => 'pecl',
                                ensure          => 'installed',
                                header_packages => [ 'libmcrypt-dev', ],
},

With a concrete version this would be executed:

Debug: Executing: '/usr/bin/pear list -a'
Debug: Executing: '/usr/bin/pear -D auto_discover=1 upgrade --alldeps -f pecl.php.net/mcrypt-1.0.1'

CyberLine avatar Feb 01 '18 08:02 CyberLine

This seems to be related to Issue 158

For me it works now by using 'ensure => snapshot' instead of version or 'installed'

CyberLine avatar May 09 '18 06:05 CyberLine

I am seeing the same problem on Debian 9 using the apt provider and the default value for ensure (installed). In fact, the module tries to install non existing packages on each run. As a workaround, you can use package_prefix and package_name parameters of php::extension to avoid this. For example :

  • for imagick extension, it tries to install 'php7.0-imagick' (instead of php-imagick) on each run. I silenced it by following c33s comment (setting the package_prefix to 'php-')
  • for ctype extension, it tries to install 'php7.0-ctype'. This package doesn't exist since the ctype extension is installed by default with the 'php7.0-common' package. I silenced it by setting the package_name to 'php7.0-common'
  • for dom extension, it tries to install 'php7.0-dom'. This package doesn't exist since the dom extension is installed by the 'php7.0-xml' package. etc.

To identify quickly the right package, use Puppet output:

Notice: /Stage[main]/Php/Php::Extension[dom]/Php::Extension::Install[dom]/Package[php7.0-dom]/ensure: created (corrective)
Info: Php::Extension::Install[dom]: Scheduling refresh of Php::Extension::Config[dom]
Info: Php::Extension::Config[dom]: Scheduling refresh of Php::Config[dom]
Info: Php::Extension::Config[dom]: Scheduling refresh of Exec[/usr/sbin/phpenmod -v 7.0 -s ALL dom]
Info: Php::Config[dom]: Scheduling refresh of Php::Config::Setting[/etc/php/7.0/mods-available/dom.ini: extension]

1/ Look at the extension library filename into the ini file (last line of puppet output above):

# cat /etc/php/7.0/mods-available/dom.ini
; configuration for php xml module
; priority=20
extension=dom.so

2/ Find the package containing that file

# dpkg -S dom.so
php7.0-xml: /usr/lib/php/20151012/dom.so

FredL69 avatar May 04 '19 16:05 FredL69

This continues to be an issue for mysql in Debian, and it's a big problem because it causes php-fpm to be restarted on every Puppet run.

To reproduce:

  class { 'php':
    ensure       => present,
    fpm          => true,
    extensions => {
      mysqli => {},
    },
  }

When specifying "mysqli" (the correct name for the extension), it tries to install the package php7.3-mysqli, however this is "Provided" by the real package php7.3-mysql. So it installs fine, but on the next puppet run it notices php7.3-mysqli isn't installed and does the whole thing again.

When specifying "mysql" (as per the Debian package name), it installs the package fine and doesn't try again on every single puppet run. However it doesn't actually work because it's trying to include a library that doesn't exist:

PHP Warning:  PHP Startup: Unable to load dynamic library 'mysql.so' (tried: /usr/lib/php/20180731/mysql.so (/usr/lib/php/20180731/mysql.so: cannot open shared object file: No such file or directory), /usr/lib/php/20180731/mysql.so.so (/usr/lib/php/20180731/mysql.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
^C

davidc avatar May 07 '21 14:05 davidc

You should provide so_name => mysqli

davidc @.***> schrieb am Fr., 7. Mai 2021, 16:03:

This continues to be an issue for mysql in Debian, and it's a big problem because it causes php-fpm to be restarted on every Puppet run.

To reproduce:

class { 'php': ensure => present, fpm => true, extensions => { mysqli => {}, }, }

When specifying "mysqli" (the correct name for the extension), it tries to install the package php7.3-mysqli, however this is "Provided" by the real package php7.3-mysql. So it installs fine, but on the next puppet run it notices php7.3-mysqli isn't installed and does the whole thing again.

When specifying "mysql" (as per the Debian package name), it installs the package fine and doesn't try again on every single puppet run. However it doesn't actually work because it's trying to include a library that doesn't exist:

PHP Warning: PHP Startup: Unable to load dynamic library 'mysql.so' (tried: /usr/lib/php/20180731/mysql.so (/usr/lib/php/20180731/mysql.so: cannot open shared object file: No such file or directory), /usr/lib/php/20180731/mysql.so.so (/usr/lib/php/20180731/mysql.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 ^C

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/voxpupuli/puppet-php/issues/387#issuecomment-834426916, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABPYIKNFF2IDXVBGJ4QSIDTMPXKHANCNFSM4D47VEAA .

CyberLine avatar May 07 '21 14:05 CyberLine

Thanks, I can do that but I feel it belongs in this module which already has conditionals for OS type and version.

davidc avatar May 07 '21 14:05 davidc

I'm still hitting this on Ubuntu 22.04.

The only solution that avoids (knowing and) specifying so_name is to specify Package { allow_virtual => true }.

The down-side of that is now all Package requests will allow virtual packages, which is presumably slower (otherwise why would they not enable it by default?)

Now I just need to find out why ext_tool_enable_sodium runs each time.

IBBoard avatar Apr 11 '23 19:04 IBBoard