简体   繁体   English

更改 docker-compose.yml 以使用 python 添加端口

[英]Alter docker-compose.yml to add ports with python

def make_file():
    
    read_file = r'C:\Users\~\Desktop\sample.yml'
    write_file = r'C:\Users\~\Desktop\sample_out.yml'    
    
    f = open(read_file, 'r')
    lst = [line for line in f]            
    f.close()

    ports = 'ports:\n'
    for index in range(len(lst)):
        if "system_frontend:" in lst[index]:            
            count_spaces = len(lst[index+1]) - len(lst[index+1].lstrip(' '))
            
            lst.insert(index+1, ports)
            lst[index+1] = lst[index+1].rjust(count_spaces)            
            # lst.insert(index+1, " "*count_spaces + ports + " "*count_spaces + "- \"0.0.0.0:5000:80\"\n") ## Did it this way, but it's not the best option.

    with open(write_file, 'w', encoding='utf-8') as file:
        for line in lst:
            file.write(line) 

The task is to place a certain amount of spaces in needed line(before str 'ports:', so it would look like ' ports:').任务是在需要的行中放置一定数量的空格(在 str 'ports:' 之前,所以它看起来像 'ports:')。

fragment from .yml来自 .yml 的片段

services:
  system_frontend:
    image: ${DOCKER_REGISTRY}/frontend:${CONTAINER_VERSION}
    logging: *id001
    environment:
      SSL_CERTIFICATE: ${SSL_CERTIFICATE:-}
      SSL_CERTIFICATE_KEY: ${SSL_CERTIFICATE_KEY:-}
      ENABLE_CORS: ${ENABLE_CORS:-}
      FRONTEND_URL: ${FRONTEND_URL:-}
      METRICS_PUSHGATEWAY: ${METRICS_PUSHGATEWAY:-}
    volumes:
      - ssl-volume:/etc/nginx/ssl
    networks:
      system_network: null
    restart: unless-stopped
    depends_on:
      - webapi

Can't succeed.不能成功。

I'm guessing that you are trying to alter docker-compose.yaml to add ports.我猜您正在尝试更改docker-compose.yaml以添加端口。 There's 2 options, you can either do it the hard way by processing text, or use yaml.safe_load to process the content有 2 个选项,您可以通过处理文本来做这件事,或者使用yaml.safe_load来处理内容

Here's my take on how you can do it.这是我对如何做到这一点的看法。 Give it a try and see if it fits your needs试一试,看看它是否符合您的需求

import yaml


# manually processing text file
def update_port_value_manual(read_file: str, write_file: str, ports: list):
    f = open(read_file, 'r')
    lst = [line for line in f]
    f.close()

    for index in range(len(lst)):
        if "system_frontend:" in lst[index]:
            count_spaces = len(lst[index + 1]) - len(lst[index + 1].lstrip(" "))
            inserted_content = count_spaces * " " + "ports:\n"
            inserted_content += "".join([f"{' ' * count_spaces}- {host_port}:{container_port}\n"
                                         for host_port, container_port in ports])
            lst.insert(index + 1, inserted_content)
            break

    with open(write_file, 'w', encoding='utf-8') as file:
        for line in lst:
            file.write(line)


# use yaml for easier processing
def update_port_value_yaml(read_file: str, write_file: str, ports: list):
    with open(read_file, "r") as read_yml:
        content = yaml.safe_load(read_yml)

    content.get("services").get("system_frontend").update(ports=[f"{host_port}:{container_port}"
                                                                 for host_port, container_port in ports])

    with open(write_file, "w") as write_yml:
        yaml.dump(content, write_yml)


def main():
    read_file = "sample.yml"
    write_file = "sample_out.yaml"

    ports = [(8081, 8081), (8080, 8080)]

    update_port_value_manual(read_file, write_file, ports)
    # update_port_value_yaml(read_file, write_file, ports)

I think this is what you are trying to achieve.我认为这就是您要实现的目标。 The main difference between your code and this is I added a break statement so the loop doesn't keep performing actions after the target line has been found.您的代码与此代码之间的主要区别是我添加了一个 break 语句,因此在找到目标行后循环不会继续执行操作。

def make_file():

    read_file = r'sample.yml'
    write_file = r'sample_out.yml'
    f = open(read_file, 'r')
    lst = [line for line in f]
    f.close()
    ports = 'ports:\n'
    spaces = 0
    for index in range(len(lst)):
        if "system_frontend:" in lst[index]:
            spaces += lst[index+1].count(" ") - 1
            break
    lst.insert(index + 1, (" "* spaces) + ports)
    with open(write_file, 'w', encoding='utf-8') as file:
        for line in lst:
            file.write(line)
make_file()

Please note that there are better ways to work with yaml files.请注意,有更好的方法来处理 yaml 文件。 Check out pyyaml in PyPi.pyyaml中查看 pyyaml。

output

services:
  system_frontend:
    ports:
    image: ${DOCKER_REGISTRY}/frontend:${CONTAINER_VERSION}
    logging: *id001
    environment:
      SSL_CERTIFICATE: ${SSL_CERTIFICATE:-}
      SSL_CERTIFICATE_KEY: ${SSL_CERTIFICATE_KEY:-}
      ENABLE_CORS: ${ENABLE_CORS:-}
      FRONTEND_URL: ${FRONTEND_URL:-}
      METRICS_PUSHGATEWAY: ${METRICS_PUSHGATEWAY:-}
    volumes:
      - ssl-volume:/etc/nginx/ssl
    networks:
      bimeister_network: null
    restart: unless-stopped
    depends_on:
      - webapi

You insert a line while loop through it, you should leave the original lines intact and use another list to store output, this is what I would do:您在循环中插入一行,您应该保留原始行并使用另一个列表来存储输出,这就是我要做的:

def make_file():
    read_file = r'sample.yml.txt'
    write_file = r'output.yml.txt'    
    
    ports = 'ports:\n'

    with open(read_file, 'r', encoding='UTF-8') as f, open(write_file, 'w', encoding='utf-8') as o:
        while (line := f.readline()):

            o.write( line )

            if "system_frontend:" in line:
                next_line = f.readline()
                count_spaces = next_line.count(" ") - 1
                next_line = next_line.rjust(count_spaces)
                
                o.write(ports)
                o.write(next_line)

make_file()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 带有 docker-compose.yml 的 Dockerfile - Dockerfile with docker-compose.yml 在 docker-compose.yml 中运行 Python package 和 multiple.py 脚本 - Run Python package with multiple .py scripts in docker-compose.yml 使用PyYAML编辑docker-compose.yml - Editing docker-compose.yml with PyYAML 什么是运行 python 脚本的基本 Dockerfile/docker-compose.yml(使用特定版本的 python/包) - what is a bare-bones Dockerfile/docker-compose.yml to run python scripts (with specific versions of python/packages) 在文件 Dockerfile、docker-compose.yml、python.py 和 Z2591C98B70119FE6248Z198B1E4 之间共享值 - sharing values among files Dockerfile, docker-compose.yml, python.py, and shell 导航到 docker-compose.yml 文件时遇到问题 - Have problem to navigate to a docker-compose.yml file MacOS:如何使用 docker-compose.yml 和 Dockerfile 挂载卷? - MacOS: How to mount volumes using docker-compose.yml and Dockerfile? 未在服务 docker-compose.yml 中指定卷 - Not specifying volumes within service docker-compose.yml 设置 docker-compose.yml 以运行 celery worker 和 celery beat 以 redis 作为代理的 django 项目 - Setting up docker-compose.yml to run celery worker and celery beat for a django project with redis as broker docker - 如何从 env.ini 文件外部为 docker-compose.yml 文件设置环境数据库? - docker - How to set up environment database for docker-compose.yml file from env.ini file outide?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM