1

I'm pretty new to Puppet and Solaris, and I'm running into an issue installing a package on a Solaris 10 VM using Puppet. As part of my testing, I wanted to see if I could install Java 6 update 43 on a Solaris 10 VM that only had Java 5 update 24. Shown below is the issue I'm having and my question.

Environment

Solaris Version: SunOS 5.10 Generic_142910-17 i386

Puppet Version: 3.1.1

Problem

It seems that if a package isn't already installed on Solaris, Puppet won't install it. Puppet throws the following message:

Error: /Stage[main]/Java::Jdk_solaris/Package[SUNWj6cfg]: Could not evaluate: Unable to get information about package SUNWj6cfg because of: No message

What's Happening

When puppet attempts to install a package on a Solaris machine, it runs the following command before trying to install the package (I saw this when the --debug flag is turned on during a puppet run):

pkginfo -l [whatever the package name is]

Example from the puppet agent --test --debug output:

Debug: Executing '/usr/bin/pkginfo -l'
Debug: Executing '/usr/bin/pkginfo -l SUNWj6cfg'
Error: /Stage[main]/Java::Jdk_solaris/Package[SUNWj6cfg]: Could not evaluate: Unable to get information about package SUNWj6cfg because of: No message

When pkginfo is looking for a package name that doesn't exist (i.e. it isn't installed or the name is wrong, etc), it returns an error, like so:

vagrant@puppet-master:[/etc/puppet/manifests] $ pkginfo -l SUNWj6cfg
ERROR: information for "SUNWj6cfg" was not found

Okey doke - that makes sense why puppet is getting an error. Fair enough. That leads me to these questions:

My Question

Why is Puppet checking to see if the package exists before trying to install it? Is there a way to bypass this check so Puppet will install a "brand new" package?

Based on what I'm seeing, it seems like Puppet can only install packages that already exist (i.e. pkginfo can find them) on the server. That doesn't seem like desirable behavior. I imagine there are plenty of cases when I'd want to have Puppet install a package that never existed on a Solaris server before. It's been my experience that if a package already exists, pkgadd will overwrite the package w/a new one.

For example, if I want to install Java 6 update 43 on a Solaris 10 machine that has Java 6 update 21, pkgadd will happily overwrite the existing SUNWj6* packages. Furthermore, if the SUNWj6* packages don't exist at all (i.e. I completely remove Java 6 via pkgrm), pkgadd will merrily install them.

I'd like to understand why Puppet would behave this way. Am I totally missing something? Am I even making sense?

Manifests

For completeness (and word count, I guess), here are my puppet manifests (the relevant ones, anyway):

/etc/puppet/modules/java/manifests/init.pp:
class java ($distribution, 
            $version, 
            $update
) {
    $class_prefix = $distribution ? { 
        jdk => 'java::jdk',
        jre => 'java::jre',
     }

    case $::operatingsystem {
        'RedHat', 'CentOS': {
            class { "${java::class_prefix}_redhat": 
                version => "${java::version}" 
            } 
            ->
            Class["java"]
        }

        'Solaris': {

            class { "${java::class_prefix}_solaris": 
                version => "${java::version}", 
                update  => "${java::update}",
            } 
            ->
            Class["java"]
        }
    }
}

/etc/puppet/modules/java/manifests/jdk_solaris.pp:
class java::jdk_solaris ($version,
                         $update
) {
    $working_dir        = "/opt/tmp"
    $zip_file_name_32   = "jdk-${version}u${update}-solaris-i586.tar.Z"
    $zip_file_name_64   = "jdk-${version}u${update}-solaris-x64.tar.Z"
    $admin_file         = "java_admin"
    $java_packages      = [ "SUNWj6cfg", 
                            "SUNWj6dev", 
                            "SUNWj6jmp", 
                            "SUNWj6man", 
                            "SUNWj6rt" ]

    file { 
        "${java::jdk_solaris::working_dir}/${java::jdk_solaris::zip_file_name_32}":
        ensure  => file,
        source  => "puppet:///modules/java/${java::jdk_solaris::zip_file_name_32}";

        "${java::jdk_solaris::working_dir}/${java::jdk_solaris::admin_file}":
        ensure  => file,
        source  => "puppet:///modules/java/${java::jdk_solaris::admin_file}";

        "${java::jdk_solaris::working_dir}/SUNWj6cfg/install/checkinstall":
        ensure  => file,
        source  => "puppet:///modules/java/SUNWj6cfg/checkinstall",
        require => Exec["zcat_32"];

        "${java::jdk_solaris::working_dir}/SUNWj6dev/install/checkinstall":
        ensure  => file,
        source  => "puppet:///modules/java/SUNWj6dev/checkinstall",
        require => Exec["zcat_32"];

        "${java::jdk_solaris::working_dir}/SUNWj6jmp/install/checkinstall":
        ensure  => file,
        source  => "puppet:///modules/java/SUNWj6jmp/checkinstall",
        require => Exec["zcat_32"];

        "${java::jdk_solaris::working_dir}/SUNWj6man/install/checkinstall":
        ensure  => file,
        source  => "puppet:///modules/java/SUNWj6man/checkinstall",
        require => Exec["zcat_32"];

        "${java::jdk_solaris::working_dir}/SUNWj6rt/install/checkinstall":
        ensure  => file,
        source  => "puppet:///modules/java/SUNWj6rt/checkinstall",
        require => Exec["zcat_32"];
    }

    file { "${java::jdk_solaris::working_dir}":
        ensure  => directory,
    }

    exec { "zcat_32":
        cwd     => "${java::jdk_solaris::working_dir}",
        command => "zcat ${java::jdk_solaris::zip_file_name_32} | tar -xf -",
        creates => [
            "${java::jdk_solaris::working_dir}/SUNWj6cfg",
            "${java::jdk_solaris::working_dir}/SUNWj6dev", 
            "${java::jdk_solaris::working_dir}/SUNWj6jmp", 
            "${java::jdk_solaris::working_dir}/SUNWj6man",
            "${java::jdk_solaris::working_dir}/SUNWj6rt" 
        ],
        path    => "/usr/bin:/usr/sbin:/bin:/sbin:/usr/local/bin:/usr/local/sbin:/opt/csw/bin:/opt/csw/sbin",
        require => [
            File["${java::jdk_solaris::working_dir}"],
            File["${java::jdk_solaris::working_dir}/${java::jdk_solaris::zip_file_name_32}"],
        ],
    }                  

#------------------------------------------------------------------------------------------------------------------------
# INSTALL JDK
#------------------------------------------------------------------------------------------------------------------------

    package { $java_packages:
        ensure      => installed,
        source      => "${java::jdk_solaris::working_dir}",
        adminfile   => "${java::jdk_solaris::working_dir}/${java::jdk_solaris::admin_file}",
        require     => [
            Exec["zcat_32"],
            File[
                "${java::jdk_solaris::working_dir}/SUNWj6cfg/install/checkinstall",
                "${java::jdk_solaris::working_dir}/SUNWj6dev/install/checkinstall",
                "${java::jdk_solaris::working_dir}/SUNWj6jmp/install/checkinstall",
                "${java::jdk_solaris::working_dir}/SUNWj6man/install/checkinstall",
                "${java::jdk_solaris::working_dir}/SUNWj6rt/install/checkinstall"
            ] # end file array
        ], # end require array
    }

#------------------------------------------------------------------------------------------------------------------------
# CLEAN UP AFTER INSTALLATION
#------------------------------------------------------------------------------------------------------------------------

    exec { "jdk_solaris_cleanup":
        cwd     => "${java::jdk_solaris::working_dir}",
        command => "rm -r ${java::jdk_solaris::admin_file} SUNWj* THIRDPARTYLICENSEREADME.txt COPYRIGHT LICENSE README.html ${java::jdk_solaris::zip_file_name_32}",
        path    => "/usr/bin:/usr/sbin:/bin:/sbin:/usr/local/bin:/usr/local/sbin:/opt/csw/bin:/opt/csw/sbin",
        require => Package[$java_packages],
    }
}

1 Answers1

0

I posted the same question on ask.puppetlabs.com, and here is the answer I received:

How should puppet know, if a package is brand-new? Puppet has to check if the package is already installed.

But this looks like a recent regression bug in the sun package provider because having a short glance at it puppet neither checks the returncode of the pkginfo command, nor does it parse the output for known error messages.

So if you can file a bug at projects.puppetlabs.com/issues, I'll try to look at the issue when I come home. When you file a bug, please drop the ticket number as a comment.

I have created ticket 20629 with the Puppet Labs folks to track this issue.