【问题标题】:How to call parameterized Jsonnet from bash?如何从 bash 调用参数化的 Jsonnet?
【发布时间】:2018-01-23 23:28:43
【问题描述】:

我不明白如何最好地参数化 Jsonnet 文件,以便我可以从 bash 和另一个 Jsonnet 文件中调用同一个文件。

假设我有一个名为 template.jsonnet 的简单模板:

{
  // Required arguments
  name:: error "'name' must be specified",
  port:: error "'port' must be specified",

  ...,
}

我可以很容易地将它合并到另一个 Jsonnet 文件中,并提供其所需的参数值:

{
  local template = = import "./template.jsonnet";

  template + {
    name:: "service",
    port:: 8080,
}

我正在努力确定我可以从 bash 调用 template.jsonnet 以获得相同结果的预期方式。

我可以使用--ext-str,但这似乎需要std.extVar(x)

GitHub issue 建议 --tla-code 可能是 std.extVar() 的替代品,但我不明白如何使用它来满足我的需要。

一个后续问题是:对于一个参数这是一个数组,如何做到这一点:

{
  local template = = import "./template.jsonnet";

  template + {
    name:: "service",
    port:: [8080,8081,8082],
}

【问题讨论】:

    标签: jsonnet


    【解决方案1】:

    最直接的方法是使用一些内联的jsonnet:

    jsonnet -e '(import "template.jsonnet") + { name: "service", port: 8080 }'
    

    为了更轻松地进行参数化,您可以使用 extVars 或顶级参数 (TLA)。

    jsonnet -e 'function(name, port) (import "template.jsonnet") + { name: name, port: port }' --tla-str name="blah" --tla-code port='[8080, 8081]'
    

    jsonnet -e '(import "template.jsonnet") + { name: std.extVar("name"), port: std.extVar("port") }' --ext-str name="blah" --ext-code port='[8080, 8081]'
    

    更好的办法是把template.jsonnet做成一个函数,使用--tla-code/--tla-str

      function(name, port) {
        name:: name,
        port:: port
        // Sidenote: the fields are hidden here, because they use ::,
        // use : to make them appear when the object is manifested.
        // Sidenote 2: You can provide default argument values. 
        // For example function(name, port=8080) makes port optional.
      }
    

    然后在另一个jsonnet文件中可以这样使用:

    local template = import "./template.jsonnet";
    {
    
      filled_template: template(
        name="service",
        port=8080 // or port=[8080,8081,8082]
      )
    }
    

    您可以使用 shell 中的模板,如下所示:

    jsonnet --tla-code name='"some name"' --tla-code port=8080 template.jsonnet
    

    注意名称如何需要引号(如果没有外部',它们将由shell 解释)。那是因为您可以将任何 jsonnet 代码传递给 tla-code 中的任何类型。

    如果你想逐字传递一个字符串,你可以使用--tla-str:

    jsonnet --tla-str name="some name" --tla-code port=8080 template.jsonnet
    

    另一方面,您可以将数组(或对象,或任何 jsonnet 代码)传递给--tla-code

    jsonnet --tla-code name='"some name"' --tla-code port='[8080, 8081, 8082]' template.jsonnet
    

    或者,如果您不想更改您的template.jsonnet,您可以使用包装文件来提供我描述的接口:

    template_func.jsonnet:

    local template = import "./template.jsonnet";
    function(name, port) template + {
      name: name,
      port: port
    }
    

    【讨论】:

    • 哇!感谢您提供详尽且解释清楚的答案。这不仅极大地帮助了我解决我的问题,而且帮助我更有效地使用 Jsonnet。谢谢。
    猜你喜欢
    • 2015-01-21
    • 2014-01-22
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    相关资源
    最近更新 更多