英文:
puppet applly and deferred functions: Error: Unknown function 'mymodule::myupcase'
问题
我正在遵循此Puppet文档来测试Deferred函数,在下面我复制了这些步骤。
- 开始创建所需的目录结构并运行一些Puppet Development Kit (pdk)命令:
cd ~/dev/src/local/puppet_tests
pdk new module mymodule
cd mymodule
pdk new class mymodule
mkdir -p lib/puppet/functions/mymodule
- 接下来,您应该将以下代码粘贴到您的
manifest/init.pp
文件中:
class mymodule {
$d = Deferred("mymodule::myupcase", ["mysecret"])
notify { example :
message => $d
}
}
class { 'mymodule': }
- 接下来,在目录
lib/puppet/functions/mymodule
下创建一个名为myupcase.rb
的文件,并粘贴以下代码:
Puppet::Functions.create_function(:'mymodule::myupcase') do
dispatch :up do
param 'String', :some_string
end
def up(some_string)
Puppet::Pops::Types::PSensitiveType::Sensitive.new(some_string.upcase)
end
end
- 现在,您应该运行
puppet apply manifest/init.pp
~/dev/src/local/puppet_tests/mymodule main*
❯ puppet apply manifests/init.pp
Notice: Compiled catalog for localhost.localdomain in environment production in 0.04 seconds
Error: Unknown function 'mymodule::myupcase'
删除init.pp
文件中以下部分的代码,它会工作,但只是因为您删除了对$d
变量的引用:
notify { example :
message => $d,
}
我在这里漏掉了什么?我的操作系统是MacOX 13.4.1,puppet 8.1.0。我使用brew安装了puppet-agent和pdk:
brew install --cask puppetlabs/puppet/puppet-agent
brew install --cask puppetlabs/puppet/pdk
编辑:
我进行了额外的测试,现在使用pdk new function
来创建函数,但错误仍然存在:
cd ~/dev/src/local/puppet_tests
pdk new module mymodule
cd mymodule
pdk new class mymodule
pdk new function myupcase --type=v4
它创建了一个名为spec/
的附加目录和一些附加文件。最终的myupcase.rb
如下:
# frozen_string_literal: true
# https://github.com/puppetlabs/puppet-specifications/blob/master/language/func-api.md#the-4x-api
Puppet::Functions.create_function(:'mymodule::myupcase') do
dispatch :myupcase do
param 'String', :a
return_type 'String'
end
# 下面的函数由puppet调用,必须与上面定义的puppet函数的名称匹配。您可以在下面设置所需的参数,并且puppet将强制执行这些参数,因此根据需要更改x,尽管在dispatch方法中只需要一个参数。
def myupcase(x)
x.upcase
end
# 您还可以在此代码块中定义其他辅助方法
end
init.pp
文件保持不变。
英文:
I'm following this puppet doc to test Deferred functions, below I replicate the steps.
- start creating the required directory strucutre and running some Puppet Develpment Kit (pdk) commands:
cd ~/dev/src/local/puppet_tests
pdk new module mymodule
cd mymodule
pdk new class mymodule
mkdir -p lib/puppet/functions/mymodule
- Next, you should paste the code below in your
manifest/init.pp
file:
class mymodule {
$d = Deferred("mymodule::myupcase", ["mysecret"])
notify { example :
message => $d
}
}
class { 'mymodule': }
- Next, create a file name
myupcase.rb
under the directorylib/puppet/functions/mymodule
and paste the code below:
Puppet::Functions.create_function(:'mymodule::myupcase') do
dispatch :up do
param 'String', :some_string
end
def up(some_string)
Puppet::Pops::Types::PSensitiveType::Sensitive.new(some_string.upcase)
end
end
- Now, you should run the
puppet apply manifest/init.pp
~/dev/src/local/puppet_tests/mymodule main*
❯ puppet apply manifests/init.pp
Notice: Compiled catalog for localhost.localdomain in environment production in 0.04 seconds
Error: Unknown function 'mymodule::myupcase'
Removing the following part of the code in the init.pp
file, it works, but just because you remove the reference to the $d
variable:
notify { example :
message => $d,
}
What am I missing here ?
My S.O. is MacOX 13.4.1, puppet 8.1.0.
Installed both puppet-agent and pdk using brew:
brew install --cask puppetlabs/puppet/puppet-agent
brew install --cask puppetlabs/puppet/pdk
EDITED:
I have made an additional test, now using the pdk new function
to create the function, but the error persists:
cd ~/dev/src/local/puppet_tests
pdk new module mymodule
cd mymodule
pdk new class mymodule
pdk new function myupcase --type=v4
It have created some additional directory named spec/
with some additional files. The final myupcase.rb
is:
# frozen_string_literal: true
# https://github.com/puppetlabs/puppet-specifications/blob/master/language/func-api.md#the-4x-api
Puppet::Functions.create_function(:"mymodule::myupcase") do
dispatch :myupcase do
param 'String', :a
return_type 'String'
end
# the function below is called by puppet and and must match
# the name of the puppet function above. You can set your
# required parameters below and puppet will enforce these
# so change x to suit your needs although only one parameter is required
# as defined in the dispatch method.
def myupcase(x)
x.upcase
end
# you can define other helper methods in this code block as well
end
The init.pp
file remains the same.
答案1
得分: 1
函数本身看起来没问题,而且你似乎已经正确地放置在你的模块中。puppet apply
找不到它很可能是因为你的模块不在它的模块路径中(你已经确认过了)。如果主类尝试使用模块的任何其他内容,比如其他类、定义的类型、模块数据等,会出现类似的错误。
总的来说,文档的最后一步,在通过apply
应用manifests/init.pp
来测试函数,似乎是非常不明智的。当它确实起作用来测试函数时,那只是因为模块的init.pp
在顶层作用域包含了class { 'mymodule': }
,这是另一个严重的问题。
以下是你应该做的:
-
从你的模块的
init.pp
中移除类声明class { 'mymodule': }
。它根本不应该在那里。 -
确保你模块目录的父目录(
~/dev/src/local/puppet_tests
)在 Puppet 的模块路径中。 -
如果你想用
puppet apply
进行测试,那么创建一个单独的清单文件,随便放在哪里:test.pp
include mymodule
注意:作为一个通用原则,更喜欢类似
include
的类声明,而不是像我们从init.pp
中删除的那种类似资源的声明。使用命令
/path/to/puppet apply path/to/test.pp
来运行测试。
英文:
The function itself looks fine, and you appear to have placed it properly in your module. That puppet apply
does not find it likely arises from your module not being in its module path (and you have already confirmed this). Similar errors would arise if the main class tried to use any other contents of the module: other classes, defined types, module data, etc.
Overall, the last step of the documentation, wherein you test the function by apply
ing manifests/init.pp
seems very ill advised, and when it does work to test the function, that's only because the module's init.pp
contains class { 'mymodule': }
at top scope, which is a whole other level of bad.
This is what you should do instead:
-
remove the class declaration
class { 'mymodule': }
from your module'sinit.pp
. It simply should not be there. -
ensure that the parent directory (
~/dev/src/local/puppet_tests
) of your module directory is in Puppet's modulepath. -
if you want to test with
puppet apply
then create a separate manifest for that, anywhere:test.pp
include mymodule
Note: as a general rule, prefer include-like class declarations such as that over resource-like ones such as we removed from
init.pp
.Use the the command
/path/to/puppet apply path/to/test.pp
to run the test.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论