Vagrant 如何仅在源存在的情况下复制文件?

Vagrant 如何仅在源存在的情况下复制文件?,vagrant,puppet,Vagrant,Puppet,我试图提供一个流浪的虚拟机,允许用户提供自己的bash_profile.local,但我不希望在虚拟机的vcs repo中跟踪此文件。我有一个跟踪的bash_profile.local.dist文件,他们可以重命名它。如何告诉puppet仅在源文件存在时创建文件?它目前工作正常,但在设置期间记录了一个错误,这就是我试图避免的 这是舱单: class local { file { '.bash_profile.local': source => 'puppet:///

我试图提供一个流浪的虚拟机,允许用户提供自己的bash_profile.local,但我不希望在虚拟机的vcs repo中跟踪此文件。我有一个跟踪的bash_profile.local.dist文件,他们可以重命名它。如何告诉puppet仅在源文件存在时创建文件?它目前工作正常,但在设置期间记录了一个错误,这就是我试图避免的

这是舱单:

class local
{
    file { '.bash_profile.local':
        source => 'puppet:///modules/local/bash_profile.local',
        path => '/home/vagrant/.bash_profile.local',
        replace => false,
        mode => 0644,
        owner => 'vagrant',
        group => 'vagrant',
    }
}

您可以通过以下方式滥用文件:

$a = file('/etc/puppet/modules/local/files/bash_profile.local','/dev/null')
if($a != '') {
    file { '.bash_profile.local':
        content => $a,
        ...
    }
}

这并不完全是您所要求的,但是您可以在源代码中提供多个路径,因此如果用户没有提供自己的路径,您可以拥有一个默认的空文件

class local
{
    file { '.bash_profile.local':
        source => [
            'puppet:///modules/local/bash_profile.local',
            'puppet:///modules/local/bash_profile.local.default'
        ],
        path => '/home/vagrant/.bash_profile.local',
        replace => false,
        mode => 0644,
        owner => 'vagrant',
        group => 'vagrant',
    }
}

您可以尝试以下方法:

file { 'bash_profile.local':
    ensure => present,
    source => ['puppet:///modules/local/bash_profile.local', '/dev/null'],
    path   => '/home/vagrant/.bash_profile.local',
    before => Exec['clean-useless-file'],
}
exec { 'clean-useless-file':
    command => 'rm .bash_profile.local',
    onlyif  => 'test -s .bash_profile.local',
    cwd     => '/home/vagrant',
    path    => '/bin:/usr/bin',
}
如果管理员没有在modules/local/bash_profile.local中提供“.bash_profile.local”的副本,则文件资源将使用第二个源,然后创建一个空白文件。然后,“onlyif”测试失败,exec将删除无用的空白文件

以这种方式使用此代码可能会有点麻烦,但它比资源调配失败要好。您可以评估在您的情况下保留空白的.bash_profile.local文件是否可以。我通常使用一种变体,使用wget而不是rm,从互联网上获取该文件的新副本,如果该文件尚未作为源提供


如果您使用的是puppetmaster,请注意,您可以使用它来配置自己的服务器,根据.bash_profile.local是否存在来显示目录的两个版本。

技巧不错,谢谢。如果有人正在阅读此文件并想知道发生了什么,file()将尝试依次读取每个文件,直到成功,因此如果第一个文件不存在,它将读取/dev/null,返回“”。为什么不在文件资源和bash测试中使用除非或onlyif?这很好,但是我想补充一点,如果您复制这个答案中的代码并在路径中粘贴一个变量,单引号意味着这些变量不会被解释。如果使用变量,请将单引号更改为双引号。(:@mestachs:
文件
在puppetmaster上工作,而不是在客户端上工作,这就是诀窍。在puppet 3.8中,是否可以这样做,但可以使用箭头运算符将此子句作为链接规则包含?即
->
运算符