Error: 未知函数 ‘mymodule::myupcase’

huangapple go评论45阅读模式
英文:

puppet applly and deferred functions: Error: Unknown function 'mymodule::myupcase'

问题

我正在遵循此Puppet文档来测试Deferred函数,在下面我复制了这些步骤。

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.

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 directory lib/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 applying 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's init.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.

huangapple
  • 本文由 发表于 2023年7月20日 22:04:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76730718.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定