使用拉梅尔亚姆勒更新包含多个yaml的yaml文件中的yaml块

2024-10-04 03:18:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含几个yaml块的yaml文件。可以看到文件here。在

基本上,我试图更新文件最后一个yaml块中的一个图像键(ctrl+f blockfreight/go-bftx:)的值。但是,我想保留文件的所有内容(包括注释),除了我正在更新的一个值。在

我有以下代码:

"""
Retrieves a truncated version of the latest git commit sha and updates 
the go-bftx container image tag in app.yaml
"""

import sys
import ruamel.yaml
from subprocess import check_output

yaml_path = 'app.yaml'
for yaml_block in ruamel.yaml.round_trip_load_all(stream=open(yaml_path)):
    pass

# parse the most recent git commit sha from command line
docker_image = 'blockfreight/go-bftx:ci-cd-' + check_output('git log -1 -- pretty=format:%h'.split()).decode()

# update go-bftx image with most recent git-commit-sha tag in the StatefulSet block
yaml_block['spec']['template']['spec']['containers'][1]['image'] = docker_image

ruamel.yaml.round_trip_dump(yaml_block, sys.stdout)

这将成功地编辑值,保持注释的完整性,但只将最终的yaml块发送到stdout。在

有没有办法让我只编辑第六个(也是最后一个)yaml块应用程序yaml,并保留文件的其余部分(包括注释)?在

我尝试用if语句替换上面代码中的pass,该语句将前五个yaml发送到stdout,然后编辑第六个值中的值,并将其发送到stdout。我的想法是使用bash将所有的stdout发送到一个文件(例如python app_modifier.py > app1.yaml),但这只发送第六个yaml的输出。在

代码是这样的:

^{pr2}$

如有任何帮助,我们将不胜感激!谢谢您!在


Tags: 文件the代码inimageimportgitapp
1条回答
网友
1楼 · 发布于 2024-10-04 03:18:34

您的文件由多个YAML文档组成,这是您使用round_trip_load_all读取的,它为您提供了一个生成器。在

如果使用round_trip_dump()将其写回,则永远不会得到原始文件中的 -YAML文档分隔符。在

您可能可以使用生成器和round_trip_dump_all,因为您知道要在哪个文档中进行更改,但对round_trip_load_all生成的内容进行list并对此进行操作可能更容易。我还将使用ruamel.yaml的新API来完成此操作:

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
data = list(yaml.load_all(open('app.yaml')))

# parse the most recent git commit sha from command line
# docker_image = 'blockfreight/go-bftx:ci-cd-' + check_output('git log -1   pretty=format:%h'.split()).decode()
docker_image = 'blockfreight/go-bftx:ci-cd-' + 'check_output_output'

# update go-bftx image with most recent git-commit-sha tag in the StatefulSet block
data[-1]['spec']['template']['spec']['containers'][1]['image'] = docker_image

with open('out.yaml', 'w') as ofp:
    yaml.dump_all(data, ofp)

上面的基本上是起作用的。out.yaml差异与您想要进行的更改有关,以及一些空白标准化(缩进,在[ "之间)当然是一次性的。在

这种方法有两个主要问题:

  • 文件中的第一个YAML文档没有内容,因此其注释不能从任何映射/序列挂起,也不会被保留
  • 第二个YAML文档有一个最后的注释(# // Initializes BFTX Service to interact with endpoints),它被删除了。这很可能是拉梅尔亚姆勒它只出现在多文档文件中,我必须调查

要解决第一个问题,您只能将该文档作为没有ruamel.yaml的普通行来读取。当你这样做的时候,除了剩下的,你还可以做所有的事情,因为这也解决了(即规避)第二个问题:

^{pr2}$

除非您关心流样式序列中的前导尾随空格,或者使用不一致的缩进保留这三个位置,否则这应该是您想要的。diff -u app.yaml out.yaml的输出:

 - app.yaml    2018-06-23 14:41:02.256290577 +0200
+++ out.yaml    2018-06-23 14:58:09.933991459 +0200
@@ -143,7 +143,7 @@
 spec:
   selector:
     matchLabels:
-       app: bftx
+      app: bftx
   serviceName: blockfreight
   replicas: 1
   template:
@@ -151,7 +151,7 @@
       labels:
         app: bftx
     spec:
-     containers:
+      containers:
       - name: tm
         imagePullPolicy: IfNotPresent
         image: tendermint/tendermint:0.20.0
@@ -199,7 +199,7 @@
           tendermint node  moniker="`hostname`"  p2p.seeds="aeabbf6b891435013f2a800fa9e22a1451ca90fd@bftx0.blockfreight.net:8888,6e9515c2cfed19464e6ce11ba2297ecdb411103b@bftx1.blockfreight.net:8888,b8b988370783bd0e58bf926d621a47160af2bdae@bftx2.blockfreight.net:8888,8c091f4e3dc4ac27db1efd38beee012d99967fd8@bftx3.blockfreight.net:8888"  proxy_app="tcp://localhost:46658"  consensus.create_empty_blocks=false
       - name: app
         imagePullPolicy: Always
-        image: blockfreight/go-bftx:rc1
+        image: blockfreight/go-bftx:ci-cd-check_output_output
         ports:
         - containerPort: 12345
         - containerPort: 46658
@@ -247,7 +247,7 @@
         - mountPath: /etc/nginx/conf.d/pub_key.conf
           name: tmconfigdir
           subPath: pub_key_nginx.conf
-     volumes:
+      volumes:
       - name: tmconfigdir
         configMap:
           name: bftx-config
@@ -262,7 +262,7 @@
       annotations:
         volume.alpha.kubernetes.io/storage-class: anything
     spec:
-      accessModes: [ "ReadWriteOnce" ]
+      accessModes: ["ReadWriteOnce"]
       resources:
         requests:
           storage: 2Gi
@@ -271,7 +271,7 @@
       annotations:
         volume.alpha.kubernetes.io/storage-class: anything
     spec:
-      accessModes: [ "ReadWriteOnce" ]
+      accessModes: ["ReadWriteOnce"]
       resources:
         requests:
           storage: 12Mi

相关问题 更多 >