【问题标题】:Azure DevOps YAML Pipeline remove Quotes and double Backslashes from passed VariablesAzure DevOps YAML 管道从传递的变量中删除引号和双反斜杠
【发布时间】:2021-06-08 00:51:37
【问题描述】:

我有一个管道,它期望 Ansible-Playbook 作为队列时间的传递变量 (string)。将我的经典管道转换为 YAML 后,我发现 Playbook-String 中的 Quotes 丢失了。

经典管道通过 Playbook (")

---
  - 
    hosts: "all"
    gather_facts: true
    vars: 
      SoftwareFolder: "ansibleshare"
      SoftwareSource: "/mnt/{{ SoftwareFolder }}"
      AnsibleRoot: "D:/Ansible"
      Proxy: "http://www-cache.de:3128"
    tasks: 
      - 
        name: "set windows proxy settings"
        win_inet_proxy: 
          auto_detect: false
          proxy: "{{ Proxy }}"
...

YAML 管道通过 Playbook (")

---
  - 
    hosts: all
    gather_facts: true
    vars: 
      SoftwareFolder: ansibleshare
      SoftwareSource: /mnt/{{ SoftwareFolder }}
      AnsibleRoot: D:/Ansible
      Proxy: http://www-cache.de:3128
    tasks: 
      - 
        name: set windows proxy settings
        win_inet_proxy: 
          auto_detect: false
          proxy: {{ Proxy }}
...

我尝试在传递之前将 Playbook 用单引号括起来 ('${yaml}'),但这无济于事。

报价是剧本的重要组成部分,我很确定有原因,为什么管道会这样。但是作为一个利益相关者,当一个变量被传递而改变时感觉很糟糕,而且在经典的管道中没有必要这样做。

我该如何解决?


元:

18.170.30525.1 (Azure DevOps Server 2020)
on prem
API: "azure-devops-node-api": "^10.2.1"

编辑 1

ansible-playbooks 上下文中的另一个问题是 YAML 管道也会误解双反斜杠 \\,这对于 playbooks 中的 windows 路径非常重要:

经典管道通过 Playbook (\\)

      - 
        name: "msi install 7z"
        win_package: 
          path: "{{ AnsibleRoot }}\\{{ SoftwareFolder }}\\7z\\7z.msi"
          state: "present"
      - 
        name: "exe install git client"
        win_package: 
          path: "{{ AnsibleRoot }}\\{{ SoftwareFolder }}\\git\\Git.exe"
          state: "present"
          product_id: "git"
          creates_path: "C:\\Program Files\\Git\\cmd\\git.exe"
          arguments: 
            - "/SILENT"

YAML 管道通过 Playbook (\\)

      - 
        name: msi install 7z
        win_package: 
          path: {{ AnsibleRoot }}\{{ SoftwareFolder }}\7z\7z.msi
          state: present

      - 
        name: exe install git client
        win_package: 
          path: {{ AnsibleRoot }}\{{ SoftwareFolder }}\git\Git.exe
          state: present
          product_id: git
          creates_path: C:\Program Files\Git\cmd\git.exe
          arguments: 
            - /SILENT

这使得 YAML-Pipelines 很难用于该用例。 :(


编辑 2

YAML 管道内容

# NAME
name: "$(Build.BuildId)-$(Build.SourceBranchName) ($(Build.RequestedFor))"

# TRIGGER
trigger: none

# VARIABLES
variables:
  - name: "PathPlaybook"
    value: "ansible-playbook.yml"
  - name: "PathInventory"
    value: "ansible-inventory.yml"

# STAGES
stages:
  # ----------------------------------------------------------- BUILD
  - stage: "Build"

    # POOL
    pool:
      name: "Ansible"
    
    # JOBS
    jobs:
      - job:
        displayName: "Agent job"

        # STEPS
        steps:

          # BASH SCRIPT TO CREATE FILE FROM PASSED PARAMETER TO TARGET MACHINE
          - task: Bash@3
            inputs:
              targetType: "inline"
              script: |
                echo '$(Inventory)' > $(PathInventory)
                echo '$(Playbook)' > $(PathPlaybook)
                
                echo Inventory:
                echo '$(Inventory)'
                
                echo Playbook:
                echo '$(Playbook)'
          
          # ANSIBLE
          - task: Ansible@0
            displayName: Ansible Agent'
            inputs:
              playbookPathOnAgentMachine: '$(PathPlaybook)'
              inventoriesAgentMachine: file
              inventoryFileOnAgentMachine: '$(PathInventory)'
              failOnStdErr: false

说明

  • 管道接收Inventory 和Playbook 作为string
  • Bash 任务将string 写入文件并生成我在上面发布的输出(更多出于调试原因)
  • Ansible 执行文件

请记住。经典中的相同管道运行良好:


编辑 3:queueBuild 函数的参数

我为queueBuild函数使用了3个参数

  • ``buildOption = 见下文
  • 项目名称 = MyProject
  • 忽略警告 = true

buildOption 作为对象

definition:{id: 23}
parameters:'{"Inventory":"---\n  all: \n    hosts: \n      PTC-BLD-ADA5: \n        ansible_user: \"PTC-SVC-ADS-AGT\"\n        ansible_password: \"AgentPW2019\"\n        ansible_port: 5986\n        ansible_connection: \"winrm\"\n        ansible_winrm_transport: \"ntlm\"\n        ansible_winrm_server_cert_validation: \"ignore\"\n","Playbook":"---\n  - \n    hosts: \"all\"\n    gather_facts: true\n    vars: \n      SoftwareFolder: \"ansibleshare\"\n      SoftwareSource: \"/mnt/{{ SoftwareFolder }}\"\n      AnsibleRoot: \"D:\\\\Ansible\"\n      Proxy: \"http://www-cache.psitrans.de:3128\"\n    tasks: \n      - \n        name: \"set windows proxy settings\"\n        win_inet_proxy: \n          auto_detect: false\n          proxy: \"{{ Proxy }}\"\n      - \n        name: \"create directory ansible\"\n        win_file: \n          path: \"{{ AnsibleRoot }}\"\n          state: \"directory\"\n      - \n        name: \"copy software to target machine\"\n        win_copy: \n          src: \"{{ SoftwareSource }}\"\n          dest: \"{{ AnsibleRoot }}\"\n      - \n        name: \"exe install git client\"\n        win_package: \n          path: \"{{ AnsibleRoot }}\\\\{{ SoftwareFolder }}\\\\git\\\\Git.exe\"\n          state: \"present\"\n          product_id: \"git\"\n          creates_path: \"C:\\\\Program Files\\\\Git\\\\cmd\\\\git.exe\"\n          arguments: \n            - \"/SILENT\"\n      - \n        name: \"msi install 7z\"\n        win_package: \n          path: \"{{ AnsibleRoot }}\\\\{{ SoftwareFolder }}\\\\7z\\\\7z.msi\"\n          state: \"present\"\n"}'
sourceBranch:'refs/heads/master'

构建选项为 JSON

{
  "definition": { "id": 23 },
  "id": 23,
  "parameters": "{\"Inventory\":\"---\n  all: \n    hosts: \n      PTC-BLD-ADA5: \n        ansible_user: \"PTC-SVC-ADS-AGT\"\n        ansible_password: \"AgentPW2019\"\n        ansible_port: 5986\n        ansible_connection: \"winrm\"\n        ansible_winrm_transport: \"ntlm\"\n        ansible_winrm_server_cert_validation: \"ignore\"\n\",\"Playbook\":\"---\n  - \n    hosts: \"all\"\n    gather_facts: true\n    vars: \n      SoftwareFolder: \"ansibleshare\"\n      SoftwareSource: \"/mnt/{{ SoftwareFolder }}\"\n      AnsibleRoot: \"D:\\\\Ansible\"\n      Proxy: \"http://www-cache.psitrans.de:3128\"\n    tasks: \n      - \n        name: \"set windows proxy settings\"\n        win_inet_proxy: \n          auto_detect: false\n          proxy: \"{{ Proxy }}\"\n      - \n        name: \"create directory ansible\"\n        win_file: \n          path: \"{{ AnsibleRoot }}\"\n          state: \"directory\"\n      - \n        name: \"copy software to target machine\"\n        win_copy: \n          src: \"{{ SoftwareSource }}\"\n          dest: \"{{ AnsibleRoot }}\"\n      - \n        name: \"exe install git client\"\n        win_package: \n          path: \"{{ AnsibleRoot }}\\\\{{ SoftwareFolder }}\\\\git\\\\Git.exe\"\n          state: \"present\"\n          product_id: \"git\"\n          creates_path: \"C:\\\\Program Files\\\\Git\\\\cmd\\\\git.exe\"\n          arguments: \n            - \"/SILENT\"\n      - \n        name: \"msi install 7z\"\n        win_package: \n          path: \"{{ AnsibleRoot }}\\\\{{ SoftwareFolder }}\\\\7z\\\\7z.msi\"\n          state: \"present\"\n\"}",
  "sourceBranch": "refs/heads/master"
}

我的应用程序调用 queueBuild 函数并将 buildOption 作为对象,正如预期的那样。

重要的是要知道这对于 classic Pipelines 完全有效,只有 YAML Pipelines 对传递的参数进行更改,如上所述。

【问题讨论】:

  • 您能否展示您的 YAML 管道中遇到此问题的相关部分?
  • 你是如何将剧本字符串作为变量传递的。您在管道中使用了哪些任务?
  • 我用管道内容扩展了我的问题。管道使用azure-devops-node-api": "^10.2.1" api 排队。 Inventory 和 Playbook 通过 queueBuild 函数作为 BuildInterfaces.Build 传递。点击here了解更多信息。
  • 你能分享你在BuildInterfaces.Build中传递的参数字符串吗?我可以成功地将字符串传递给 yaml 管道,并保留" 和“\\”。 " 和 "\\ " 必须像这样 path: \\"{{ AnsibleRoot }}\\\\\\\\{{ SoftwareFolder }}\\\\\\\\git\\\\\\\\Git.exe\\" 在 BuildInterfaces.Build 中的参数字符串中转义
  • @LeviLu-MSFT 我将完整传递的参数添加到我的问题中。是否有一个通用的regex 来创建转义的管道参数字符串以由 YAML 管道 正确解释?

标签: azure-devops azure-pipelines


【解决方案1】:

我可以使用String.raw方法成功传递带有“和”的参数字符串。见下文:

let ps = String.raw `{"Inventory":"---\n  all: \n    hosts: \n      PTC-BLD-ADA5: \n        ansible_user: \"PTC-SVC-ADS-AGT\"\n        ansible_password: \"AgentPW2019\"\n        ansible_port: 5986\n        ansible_connection: \"winrm\"\n        ansible_winrm_transport: \"ntlm\"\n        ansible_winrm_server_cert_validation: \"ignore\"\n","Playbook":"---\n  - \n    hosts: \"all\"\n    gather_facts: true\n    vars: \n      SoftwareFolder: \"ansibleshare\"\n      SoftwareSource: \"/mnt/{{ SoftwareFolder }}\"\n      AnsibleRoot: \"D:\\\\Ansible\"\n      Proxy: \"http://www-cache.psitrans.de:3128\"\n    tasks: \n      - \n        name: \"set windows proxy settings\"\n        win_inet_proxy: \n          auto_detect: false\n          proxy: \"{{ Proxy }}\"\n      - \n        name: \"create directory ansible\"\n        win_file: \n          path: \"{{ AnsibleRoot }}\"\n          state: \"directory\"\n      - \n        name: \"copy software to target machine\"\n        win_copy: \n          src: \"{{ SoftwareSource }}\"\n          dest: \"{{ AnsibleRoot }}\"\n      - \n        name: \"exe install git client\"\n        win_package: \n          path: \"{{ AnsibleRoot }}\\\\{{ SoftwareFolder }}\\\\git\\\\Git.exe\"\n          state: \"present\"\n          product_id: \"git\"\n          creates_path: \"C:\\\\Program Files\\\\Git\\\\cmd\\\\git.exe\"\n          arguments: \n            - \"/SILENT\"\n      - \n        name: \"msi install 7z\"\n        win_package: \n          path: \"{{ AnsibleRoot }}\\\\{{ SoftwareFolder }}\\\\7z\\\\7z.msi\"\n          state: \"present\"\n"}`; 
        
let vstsdef : bi.Build = {
        definition: { id: 48 },
        parameters: ps
       };
    
let nq = await build.queueBuild(vstsdef,"TestProject")

查看以下来自 yaml 管道的输出:

【讨论】:

    猜你喜欢
    • 2018-11-01
    • 2016-03-24
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 2015-02-27
    • 2021-11-23
    相关资源
    最近更新 更多