On Tuesday, February 19, 2013 8:48:43 AM UTC-7, jcbollinger wrote:
>
>
>
> On Monday, February 18, 2013 8:41:53 AM UTC-6, Josh D wrote:
>>
>> I have a module for windows nodes that is defined like:
>>
>> class ast_win {
>>   Class['ast_win::env'] ~> Class['ast_win::restart'] -> Class['ast_win']
>>
>> ast_win::env contains a bunch of scripts that modify the environment on 
>> the host machine.  Mostly the PATH variable, but also other variables (e.g. 
>> http_proxy) that are required for downstream installations. 
>>  ast_win::restart is supposed to run any time there is an environment 
>> change.  It will restart the Puppet Agent service and prompt the user to 
>> close a command prompt, if that's how they're running the agent.  Here's 
>> the class definition for that guy:
>>
>> class ast_win::restart {
>>
>>   file {'RestartAgentBat' :
>>     ensure => file,
>>     source => 'puppet:///modules/ast_win/restart_agent.bat',
>>     path   => 'C:\programdata\puppet\restart_agent.bat',
>>     recurse => true,
>>     mode    => 0777,
>>   }
>>
>>   exec {'restart_agent':
>>     cwd         => 'C:\programdata\puppet',
>>     command     => 'C:\programdata\puppet\restart_agent.bat',
>>     subscribe   => File['RestartAgentBat'],
>>     refreshonly => true,
>>     creates     => 'C:\programdata\puppet\restart_agent.txt',
>>     onlyif      => 'cmd /c if exist restart_agent.txt (exit 1) else 
>> (exit)',
>>     path => $::path,
>>   }
>> }
>>
>> This much works.  What I'm trying to accomplish is when a restart is 
>> required, the "restart_agent" exec will return a non-zero exit status and 
>> Puppet will skip all of the resources defined in Class['ast_win'] 
>> (Class['ast_win::restart'] -> Class['ast_win']).  restart_agent.bat creats 
>> a text file that wil be deteted on future runs via the onlyif check.
>>
>> The problem I'm running into is that even though restart_agent fails, 
>> Puppet still continues onto Class['ast_win'].  Currently, I have everything 
>> commented out in that class except for a dummy exec task that always fails. 
>>  Here is an example run, where a restart should be required, restart_agent 
>> fails, and puppet continues onto Class['ast_win']:
>>
>> Info: Class[Ast_win::Env]: Scheduling refresh of Class[Ast_win::Restart]
>> Info: Class[Ast_win::Restart]: Scheduling refresh of Exec[restart_agent]
>> Notice: /Stage[main]/Ast_win::Restart/File[RestartAgentBat]/ensure: 
>> defined content as '{md5}84ef01a7640a75f2fe702e8991be9e91'
>> Info: /Stage[main]/Ast_win::Restart/File[RestartAgentBat]: Scheduling 
>> refresh of Exec[restart_agent]
>> Notice: /Stage[main]/Ast_win::Restart/Exec[restart_agent]/returns: The 
>> Puppet Agent service is stopping.
>> Notice: /Stage[main]/Ast_win::Restart/Exec[restart_agent]/returns: The 
>> Puppet Agent service was stopped successfully.
>> Notice: /Stage[main]/Ast_win::Restart/Exec[restart_agent]/returns:
>> Notice: /Stage[main]/Ast_win::Restart/Exec[restart_agent]/returns: 
>> *************
>> *************************************************************
>> Notice: /Stage[main]/Ast_win::Restart/Exec[restart_agent]/returns: 
>> Install Stage Complete. Restarting the puppet service.
>> Notice: /Stage[main]/Ast_win::Restart/Exec[restart_agent]/returns: IF 
>> USING A COMMAND PROMPT, YOU MUST NOW CLOSE IT AND OPEN A NEW ONE BEFORE 
>> CONTINUING!
>> Notice: /Stage[main]/Ast_win::Restart/Exec[restart_agent]/returns: 
>> *************
>> *************************************************************
>> Error: /Stage[main]/Ast_win::Restart/Exec[restart_agent]: Failed to call 
>> refresh: C:\programdata\puppet\restart_agent.bat returned 1 instead of one 
>> of [0]
>> Error: /Stage[main]/Ast_win::Restart/Exec[restart_agent]: 
>> C:\programdata\puppet\restart_agent.bat returned 1 instead of one of [0]
>> Notice: /Stage[main]/Ast_win/Exec[exit_init]/returns: INIT PATH <snip />
>> Error: cmd /c echo INIT PATH %PATH% & exit 1 returned 1 instead of one of 
>> [0]
>> Error: /Stage[main]/Ast_win/Exec[exit_init]/returns: change from notrun 
>> to 0 failed: cmd /c echo INIT PATH %PATH% & exit 1 returned 1 instead of 
>> one of [0]
>> Notice: Finished catalog run in 237.10 seconds
>>
>>
>> Basically, what I'm looking for is a way to say: "Always run ast_win::env 
>> before ast_win::restart.  Always run ast_win::restart before ast_win and 
>> don't run ast_win if ast_win::restart fails.  The following chain seems to 
>> fail that very last bit:
>>   Class['ast_win::env'] ~> Class['ast_win::restart'] -> Class['ast_win']
>>
>> Is there any way to accomplish what I'm trying to do?
>>
>>
>
> Maybe.  It becomes very tricky when you throw signaling relationships and 
> refreshes into the middle of a dependency chain (as opposed to at the 
> end).  See http://projects.puppetlabs.com/issues/5876 for a discussion of 
> some of the issues, and vote for it if you're so inclined.  That issue has 
> got to rank among the top vote getters, especially for open issues of its 
> age.
>
> It can also be tricky to model processes in Puppet, because Puppet focuses 
> on state.  Puppet is not a script engine, but in this regard you are trying 
> to use it as one.
>
> I suspect that what is happening is that class ast_win::restart *
> synchronizes* successfully, and then, as a separate matter, the Exec 
> within fails to *refresh*.  Class ast_win is clear to be applied because 
> only the synchronization success is required to satisfy the relationship.
>
> Maybe you can trap the event from class ast_win::env so that the Exec 
> refresh becomes an ordinary sync.  The 'onlyif' parameter makes me think 
> you might already have been trying something like that.  It might work like 
> this:
>
> class ast_win::restart {
>
>   # note: the 'recurse' parameter is meaningful only for directories
>   file {'RestartAgentBat' :
>     ensure => file,
>     source => 'puppet:///modules/ast_win/restart_agent.bat',
>     path   => 'C:\programdata\puppet\restart_agent.bat',
>     mode    => 0777,
>   }
>
>   # Here is where the magic happens.  When this exec is synced,
>   # it ensures that file c:\programdata\puppet\restart_agent.txt is
>   # absent, but when it is refreshed, it ensures that file present:
>   exec { 'restart_agent_flag':
>     cwd         => 'C:\programdata\puppet',
>     command => 'cmd /c if exist restart_agent.txt del restart_agent.txt',
>     refresh => 'cmd /c echo restart > restart_agent.txt'
>   }
>
>   # This is now a normal exec, not refreshonly.  Note also that it uses
>   # 'require' instead of 'subscribe', including for 
> File['RestartAgentBat'].
>   # It doesn't need to refresh when the batch file changes; it just
>   # needs the batch file to be up to date before running it.
>   exec {'restart_agent':
>     cwd         => 'C:\programdata\puppet',
>     command => 'C:\programdata\puppet\restart_agent.bat',
>     require   => [File['RestartAgentBat'], Exec[restart_agent_flag]],
>     onlyif      => 'cmd /c if exist restart_agent.txt (exit 0) else (exit 
> 1)',
>     path => $::path,
>   }
> }
>
>
> John
>
>
This got put on the back burner for a few months, and I just recently 
revisited it.  Just wanted to let everyone know that the approach John laid 
out, more or less works.  I do have issues with attempting to restart the 
puppet service when not running the puppet agent from the command line, but 
that's not entirely unexpected.  Thanks a lot John for the incredibly 
detailed response.   Every time I look at those rules, I have to read 
through them slowly several times to remind myself how it works.  Not sure 
how you figured it out, but well done!

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-users.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to