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.