Ask Your Question
2

"Re-Declaring" I dont get it.

asked 2014-08-14 15:04:14 -0500

tek0011 gravatar image

updated 2014-09-15 10:23:01 -0500

First I will apologize to you all. I was thrown in to Puppet last Thursday and told I will be running it from now on. I hadnt even heard of it until Thurs.
I also ask for your patience as I am just learning the ins and outs, and have spent the last 5 hours (literally) looking at the syntax for the first time.

I am attempting to remove all references of java out of the windows path variable:

  • C:\Program Files\Java\jdk1.7.0_45\bin
  • C:\Program Files\Java\jdk1.7.0_50\bin
  • C:\Program Files\Java\jdk1.7.0_51\bin

We are using windows_path to do this.

The problem I am having is re-declaring. Typically with most languages I would just declare what I want to do on one line or loop, run it, and then declare in another loop what else I want to do, and there are no conflicts. Puppet seems different. Particularly this part of the script:

# Adds java to the path.
windows_path {'javaPath':
  ensure      => present,
  directory   => "C:\\Program Files\\Java\\$file\\bin",

Which indeed adds the new correct path. I also found I can change present to absent and it will remove that path location. Except I need it to remove ALL previous versions of java, not just the current we are trying to install.

What I cant figure out is how to do both. If I call upon windows_path twice, once in the begining to remove and again after it to add, it just tells me I cant re-declare. So there in lies my question. How do I do both?

I ask for detailed responses as this is all completely new to me. I learn fast, and will pick it up, but for now my level of puppet understanding as a whole is about 3/10. And again, I will apologize in advance for my current state of confusion. (assume its your first day learning puppet and youll know how I feel :) )

#
# Installs and manages Java on Windows machines.
# $source should be set to the name of the .exe that will be copied over.
# $package should be the name of the installed program. Easiest way to figure this out is to install manually, then look at installed program list.
# $file should be equal to the name of the files that get created by the install, such as 'jdk1.7.0_55'. Used to set the path.
#
define windows_java::setup (
  $ensure        = 'present',
  $source        = undef,
  $file          = undef,
  $package       = undef ) {

  case $::osfamily {
    Windows  : { $supported = true }
    default : { fail("The ${module_name} module is not supported on ${::osfamily} based systems") }
  }

  # Validate parameters
  if ($source == undef) {
    fail('source parameter must be set')
  }

  if ($file == undef) {
    fail('file parameter must be set')
  }

  if ($package == undef) {
    fail('package parameter must be set')
  }

  # Validate input values for $ensure
  if !($ensure in ['present', 'absent']) {
    fail('ensure must either be present or absent')
  }

  if ($caller_module_name == undef) {
    $mod_name = $module_name
  } else {
    $mod_name = $caller_module_name
  }

  if ($ensure == 'present'){
    # ensures main directory exists
    file {'C:\Program Files\Java':
      ensure => directory ...
(more)
edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
2

answered 2014-08-14 18:13:50 -0500

spuder gravatar image

Welcome to puppet.

As you are probably learning, puppet is not a scripting language; so you must rethink in terms of state, not procedures.

The reason that you are finding that you can't redeclare windows_path {'javaPath': is because each resource in a manifest must have a unique title. (Think of each resource as an object). You can't have two windows_path objects with the same title of 'javaPath'

Also as you have discovered, puppet does not do looping. See this stack overflow question for an explanation

Without having experience with puppet on windows or the windows_path module, I can't tell exactly why you are getting the error you are seeing, but it looks like you aren't including the module in your manifest.

Could you try adding

include windows_path

Then show the exact error?

edit flag offensive delete link more
0

answered 2014-08-14 20:16:35 -0500

tek0011 gravatar image

updated 2014-08-15 08:46:17 -0500

I am sorry. I should reiterate. The above code is indeed working. What my issue is, is that I can only use this:

# Adds java to the path.
windows_path {'javaPath':
  ensure      => present,
  directory   => "C:\\Program Files\\Java\\$file\\bin",
}

or this (absent):

# Adds java to the path.
windows_path {'javaPath':
  ensure      => absent,
  directory   => "C:\\Program Files\\Java\\$file\\bin",
}

however I can not do both. I need it to first remove all instances of java from the path, then re-add the one we want to add.

I attempted to do this:

# Removes java from the path.
windows_path {'removejavaPath':
  ensure      => absent,
  directory   => "C:\\Program Files\\Java\\$file\\bin",
}


# Adds java to the path.
windows_path {'javaPath':
  ensure      => present,
  directory   => "C:\\Program Files\\Java\\$file\\bin",
}

Edit: New Code with 'removejavapath'

#
# Installs and manages Java on Windows machines.
# $source should be set to the name of the .exe that will be copied over.
# $package should be the name of the installed program. Easiest way to figure this out is to install manually, then look at installed program list.
# $file should be equal to the name of the files that get created by the install, such as 'jdk1.7.0_55'. Used to set the path.
#
include windows_path

define windows_java::setup (
  $ensure        = 'present',
  $source        = undef,
  $file          = undef,
  $package       = undef ) {

  case $::osfamily {
    Windows  : { $supported = true }
    default : { fail("The ${module_name} module is not supported on ${::osfamily} based systems") }
  }

  # Validate parameters
  if ($source == undef) {
    fail('source parameter must be set')
  }

  if ($file == undef) {
    fail('file parameter must be set')
  }

  if ($package == undef) {
    fail('package parameter must be set')
  }

  # Validate input values for $ensure
  if !($ensure in ['present', 'absent']) {
    fail('ensure must either be present or absent')
  }

  if ($caller_module_name == undef) {
    $mod_name = $module_name
  } else {
    $mod_name = $caller_module_name
  }

  if ($ensure == 'present'){
    # ensures main directory exists
    file {'C:\Program Files\Java':
      ensure => directory,
    }

    # copies source executable over
    file { "C:\\Program Files\\Java\\$source":
      ensure             => present,
      source             => "puppet:///extra_files/java/windows/$source",
      before             => Package["$package"],
      source_permissions => ignore,
    }

    # Name of package must match name when installed
    package { "$package":
      ensure             => installed,
      source             => "C:\\Program Files\\java\\$source",
      install_options    => '/s',
    }

    # sets JAVA_HOME. If already existant, replaces it.
    windows_env { "JAVA_HOME=C:\\Program Files\\Java\\$file":
      mergemode => clobber,
    }

    # removes previous Java from path
    windows_path {'removejavapath':
      ensure      => absent,
      directory   => "C:\\Program Files\\Java\\jdk1.7.0_51\\bin"
    }

    # Adds java to the path.
    windows_path {'javaPath':
      ensure      => present,
      directory   => "C:\\Program Files\\Java\\$file\\bin",
     }
  } else {

    package { 'remove-package':
      name   => "$package",
      ensure => absent,
    }

    windows_env { 'JAVA_HOME':
      ensure    => 'absent',
      mergemode => clobber,
    }

    windows_path {'remove_java_path':
     ensure    => absent,
     directory => "C:\\Program Files\\Java\\$file\\bin",
    }
  }
}

Edit: output

C:\Windows\system32>puppet agent --test
Info: Retrieving pluginfacts
Warning: Copying owner/mode/group from the source file on Windows is deprecated; use source_permissions => ignore.
   (at C:/Program Files (x86)/Puppet Labs/Puppet/puppet/lib/puppet/type/file/source.rb:120:in `each')
Info: Retrieving plugin
'lspci' is not recognized as an internal or external command,
operable program or batch file.
Info: Loading facts in C:/ProgramData/PuppetLabs/puppet/var/lib/facter/facter_dot_d.rb
Info: Loading facts in C:/ProgramData/PuppetLabs/puppet ...
(more)
edit flag offensive delete link more

Comments

Puppet uses the manifests to create a dependency graph for all the nodes. Each node must exist once, but can of course have multiple relationships. As Spuder said, Puppet is not a scripting language.

ramindk gravatar imageramindk ( 2014-08-15 00:00:11 -0500 )edit

What other answers are pointing out is that a resource with a given name can only exist once. This is defined by resource type (windows_path) and title ('javaPath'). So windows_path{'javaPath':} needs to point to only ONE resource ever.

rob gravatar imagerob ( 2014-09-15 10:19:37 -0500 )edit
0

answered 2014-08-20 03:54:50 -0500

updated 2014-08-20 14:48:25 -0500

I'm quite new to Puppet myself, so I know exactly how you feel :)

Had a quick look at your snippet - please keep in mind that Puppet does not execute serially. Rather, it uses internal ordering - which is random, unless you specifically set dependencies between your resources. Example:

#removes previous Java from path
windows_path {'removejavapath':
  ensure      => absent,
  directory   => "C:\\Program Files\\Java\\jdk1.7.0_51\\bin"
}  
#Adds java to the path.
windows_path {'javaPath':
  ensure      => present,
  directory   => "C:\\Program Files\\Java\\$file\\bin",
  require => Window_path['removejavapath'],
}

Puppet will now know to execute removal before attempting to re-add the path.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2014-08-14 15:04:14 -0500

Seen: 445 times

Last updated: Aug 20 '14