Azure DevOps YAML 管道从传递的变量中删除引号和双反斜杠
Posted
技术标签:
【中文标题】Azure DevOps YAML 管道从传递的变量中删除引号和双反斜杠【英文标题】:Azure DevOps YAML Pipeline remove Quotes and double Backslashes from passed Variables 【发布时间】: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个参数
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 管道 正确解释?
【参考方案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 管道的输出:
【讨论】:
以上是关于Azure DevOps YAML 管道从传递的变量中删除引号和双反斜杠的主要内容,如果未能解决你的问题,请参考以下文章
Azure DevOps - 使用参数在 yaml 管道定义中设置路径触发器
如何在 yaml 中处理 Azure DevOps 管道中的错误?