2017-06-13 60 views
2

我是一个傀儡初学者 - 如此忍受我:) 我试图写一个模块,执行以下操作:木偶:复制文件只有在包需要安装最新的

  • 检查软件包是否安装了最新版本的软件仓库
  • 如果需要安装软件包,那么配置文件将从puppet源位置复制到客户端。然后将安装该软件包
  • 一旦文件被复制并安装软件包,运行脚本将使用客户端上的配置文件来应用必要的设置。
  • 一旦这一切完成后,删除客户端

我已经想出以下复制的文件:

class somepackage(
    $package_files_base = "/var/tmp", 
    $package_setup  = "/var/tmp/package-setup.sh", 
    $ndc_file   = "/var/tmp/somefile.ndc", 
    $osd_file   = "/var/tmp/somefile.osd", 
    $nds_file   = "/var/tmp/somefile.nds", 
    $configini_file  = "/var/tmp/somefile.ini", 
    $required_files  = ["$package_setup", "$ndc_file", "$osd_file", $nds_file", "$configini_file"]) 
{ 
    package { 'some package': 
    ensure => 'latest', 
    notify => Exec['Package Setup'], 
    } 

    file { 'Package Setup Files': 
    path => $package_files_base, 
    ensure => directory, 
    replace => false, 
    recurse => true, 
    source => "puppet:///modules/somepackage/${::domain}", 
    mode => '0755', 
    } 

    exec { 'Package Setup': 
    command  => "$package_setup", 
    logoutput => true, 
    timeout  => 1800, 
    require  => [ File['Package Setup Files']], 
    refreshonly => true, 
    notify  => Exec['Remove config files'], 
    } 

    exec { 'Remove config files': 
    path  => ['/usr/bin','/usr/sbin','/bin','/sbin'], 
    command  => "rm \"${package_setup}\" \"${ndc_file}\" \"${osd_file}\" \"${nds_file}\" \"${configini_file}\"", 
    refreshonly => true, 
    } 
} 

虽然这实现了大多数的什么,我想做的事情,我注意到在重新运行傀儡时,应用这些文件虽然被删除,但正在被复制。

我可以理解为什么会发生这种情况,但我不知道如何对它进行编码,以便只有在程序包得到更新/安装(例如,程序包未安装或旧版本)时才会复制文件。否则,每当木偶每隔30分钟(默认设置)在客户端上运行时,文件就会被一遍又一遍地复制,我假设...我试图使用replace => false来防止这种情况,但这只是意味着文件在从/var/tmp之后这是该类的第一次运行,因为它仅阻止后续运行的类重新复制文件(从我的测试中)。这确实可以防止多余的重复性复制 - 但是我只想让这些文件在第一时间消失!

这可能吗? !头好痛:(提前

感谢我们正在EL7.3运行木偶版本3.8.6

编辑:要清楚,这是我挣扎了一下:资源file { 'Package Setup Files':这种状态越来越文件复制即使包不更新/安装。如何防止这种情况的发生?

+0

从我所了解的情况来看,只有在软件包不是最新的版本时才需要执行“软件包设置文件”?那是你唯一面临的问题? –

+0

不,执行得很好 - “文件{'程序包设置文件''位是无论如何都会一直执行的文件。如果软件包已更新/安装,我只想限制这一点。 –

+0

我注意到$ package_files_base没有在任何地方定义。错字? –

回答

2

下面是一些建议。

1)建议了短期的解决办法

如果您不需要,请停止尝试清理这些文件。把它们放在/opt,忘记它们。更好的是,让Puppet在那里放置一个README文件,它会向你的未来自我和同行管理员解释他们是什么以及他们为什么在那里。

虽然我完全理解清理的愿望,但您需要权衡在某个目录中有几个旧文件的成本,而不是在Puppet代码中具有复杂逻辑的代价,这对于任何人来说都没有任何意义几个月。

这就是我会做的,根据我的经验,这也是大多数Puppet模块作者用这些类型的设置文件所做的。

2)考虑业务流程框架

这就是说,在我看来,你要使用木偶做作战任务,虽然它可以种做作战任务(通过功能,如ensure => latest等)它真的打算成为一个配置管理工具。

我建议人们使用Puppet到ensure => installed的包(确保Puppet可以正确安装应用程序,如果你需要完全重建节点);然后委托在Puppet之外应用版本升级和修补程序等问题。

这有几个原因。

木偶是声明性配置管理系统;你的Puppet代码应该定义一个结束状态。 Puppet不像一个shell脚本,它不是一个结束状态,而是定义了一些步骤,这些步骤可以强制性地改变服务器的状态,“一步一个脚印”。

的第一个问题是ensure => latest哲学。 latest没有定义单个最终状态。你的代码在X时刻的行为与Y时刻的行为不同,所以你的代码不是幂等的。

第二个问题是实用的。因为Puppet永远无法知道系统中的所有RPM及其依赖关系,所以永远无法通过使用Puppet解决RPM更新的问题。所以,无论如何,你仍然需要专门的工具来管理版本更新。因此,由于无论如何您都需要专门的工具来管理版本更新,因此在两个工具的角色之间绘制清晰的边界更清晰:始终使用Puppet来管理配置和初始安装;然后始终使用其他工具来管理更新。

好,太好了。我看到您的意见,您已经有了一个红帽卫星服务器,你已经写了:

...卫星内的一些主机已经得到百胜内 软件的旧版本。但是我们不会经常更新这个软件 .....也许每年一次。

所以,它听起来就像你正在使用木偶这里解决您正在使用卫星的方式有问题。是否可以通过修复您使用Satellite的方式来解决这个问题?如果是这样,我认为这会更清洁。

当然,有时做正确的事情是使用一个变通,这就是为什么我提供了一些其他的选择。

3)如果你真的好想木偶来清理这些文件

也许移动shell脚本内部的逻辑。例如:

class somepackage { 

    $shell = 

'#!/bin/bash 

# maybe use wget instead of puppet to get the files 
wget http://a.b/c.tgz 
tar zxf c.tgz 

# install stuff 

# clean up stuff 
' 

    file { '/usr/local/bin/installer.sh': 
    ensure => file, 
    mode => '0755', 
    content => $shell, 
    } 

    package { 'some package': 
    ensure => latest, 
    notify => Exec['installer'], 
    } 

    exec { 'installer': 
    command  => '/usr/local/bin/installer.sh', 
    refreshonly => true, 
    require  => File['/usr/local/bin/installer.sh'], 
    } 
} 
+0

她并不是在尝试编排,但第1和第3点仍然有效。 –

+0

这取决于你如何定义“编排”,但我可以告诉你,与Nigel Kersten(Puppet首席技术官)相同,我认为你不应该使用Puppet的'ensure => latest'(IIRC,墨尔本木偶营,2014 );这是一个操作/服务器维护任务,最好由Puppet之外的编排框架处理。 –

+0

他可能会说“尽量避免”而不是“永远”。 –