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:').
fragment from .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.
CodePudding user response:
I'm guessing that you are trying to alter docker-compose.yaml
to add ports.
There's 2 options, you can either do it the hard way by processing text, or use yaml.safe_load
to process the content
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)
CodePudding user response:
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.
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. Check out pyyaml
in PyPi.
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
CodePudding user response:
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()