我使用puppet-vcsrepo从github安装。代码看起来像这样:
class demo_class(
$my_repo = undef,
$my_tag = undef,
){
vcsrepo { "$my_repo",
path => "/home/user/$my_repo",
source => 'git@github.com:7yl4r/$my_repo.git',
ensure => latest,
provider => git,
}
# then declare resources specific to my_tag
}
只调用一次就可以正常工作,但我在列表上进行迭代并安装依赖项,因此有时会将此资源声明两次。我认为这大致相当于下面的代码。
class {"demo_class":
my_repo => test_repo,
my_tag => test_tag1,
}
class {"demo_class":
my_repo => test_repo,
my_tag => test_tag2,
}
执行此操作会产生服务器端“重复声明”错误,因为vcsrepo正在尝试两次映射相同的路径。但是,这正是我想要的行为:对于demo_class
声明的两个资源,要求在同一位置使用相同的repo。这样我就可以使用demo_class
声明一个或多个资源,并确保my_repo
给出的回购(可能是多个my_tag
共有的)。
如何修改此类以便我可以调用它两次而不会出现错误?
答案 0 :(得分:2)
我看到了问题。
我使用此代码重现了该问题:
define my_vcs_repo ($myRepo, $myTag) {
vcsrepo { "$myRepo-$myTag":
path => "/home/user/$myRepo",
source => "git@github.com:7yl4r/$myRepo.git",
revision => $myTag,
ensure => latest,
provider => git,
}
}
$data = [
{
myRepo => testRepo,
myTag => testTag1,
},
{
myRepo => testRepo,
myTag => testTag2,
},
]
$data.each |$i, $ref| {
$myRepo = $ref['myRepo']
$myTag = $ref['myTag']
my_vcs_repo { "$myRepo-$i":
myRepo => $myRepo,
myTag => $myTag,
}
}
然后导致:
Puppet::PreformattedError:
Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Resource Statement, Cannot alias Vcsrepo[testRepo-testTag2] to ["/home/user/testRepo"] at /
Users/alexharvey/git/modules/foo/spec/fixtures/modules/foo/manifests/init.pp:3; resource ["Vcsrepo", "/home/user/testRepo"] already declared at /Users/alexharvey/git/modules/foo/spec/fixtures/modules/foo/
manifests/init.pp:3 at /Users/alexharvey/git/modules/foo/spec/fixtures/modules/foo/manifests/init.pp:3:5 at /Users/alexharvey/git/modules/foo/spec/fixtures/modules/foo/manifests/init.pp:26 on node alexs-macbook-pro.local
问题是你要求Puppet将相同的Git模块克隆到一个目录,但是检出了两个不同的标签。这没有意义。
修复是您需要在vcsrepo路径属性中指定唯一路径,例如:
vcsrepo { "$myRepo-$myTag":
path => "/home/user/$myRepo-$myTag",
source => "git@github.com:7yl4r/$myRepo.git",
revision => 'production',
ensure => latest,
provider => git,
}
顺便说一下,我注意到你正在使用camelCase作为你的变量。不要这样做。除了Puppet不是惯用的事实之外,有些事情会在我见过的Puppet / Rspec木偶的某些版本中破裂。
使用snake_case
作为变量名和类参数名。
更新
该问题已经过编辑,现在问题是如何在多个班级中声明相同的vcsrepo
。
通常,尝试重构,这样您就不需要首先执行此操作。换句话说,只需将它移出这个类并将它放在一个只能被声明一次的地方。
如果由于某种原因无法执行此操作,那么您还可以使用virtual resources,这将允许您在将在同一节点上声明的多个类中声明它。
要做到这一点,你只需要重写你所拥有的:
@vcsrepo { $my_repo:
path => "/home/user/$my_repo",
source => "git@github.com:7yl4r/$my_repo.git",
ensure => latest,
provider => git,
}
realize Vcsrepo[$my_repo]
请记住,您无法在同一节点上两次声明类demo_class
。您需要将其转换为已定义的类型,如上所述。
以下评论中提到您还可以使用ensure_resource
和ensure_resources
;请参阅stdlib中的文档。