-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose-puller.py
More file actions
150 lines (124 loc) · 6.12 KB
/
docker-compose-puller.py
File metadata and controls
150 lines (124 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import os
import re
import shutil
import requests
import argparse
import difflib
def update_file(download_path, compose_file_path, backup_file_path, update_regex, env_file_path, env_version_variable, show_diff=False):
"""
Updates a file based on the given parameters.
Args:
download_path: Path to the download directory (can be a URL).
compose_file_path: Path to the compose file.
backup_file_path: Path to the backup directory.
update_regex: Regular expression for version extraction.
show_diff (bool, optional): Whether to show the difference between files. Defaults to False.
env_file_path (str, optional): Path to the environment file. Defaults to "./.env".
env_version_variable (str, optional): The variable name in the environment file to update.
Defaults to "version".
"""
# Download file (if URL)
if download_path.startswith("http"):
try:
response = requests.get(download_path, stream=True)
response.raise_for_status()
# Create a temporary directory for download
temp_dir = os.path.join(os.path.dirname(compose_file_path), '.updater_temp')
os.makedirs(temp_dir, exist_ok=True)
temp_file = os.path.join(temp_dir, 'temp.file')
with open(temp_file, 'wb') as f:
f.write(response.content)
print("\nDownload complete.\n")
# Read downloaded content from temporary file
with open(temp_file, 'r') as f:
download_file_content = f.read()
# Clean up temporary file and directory
os.remove(temp_file)
shutil.rmtree(temp_dir)
except requests.exceptions.RequestException as e:
print(f"Error downloading file: {e}")
return
else:
# Read file from local path
with open(download_path, 'r') as f:
download_file_content = f.read()
# Load compose file
with open(compose_file_path, 'r') as f:
compose_file_content = f.read()
# Extract versions
compose_version = re.search(update_regex, compose_file_content)
download_version = re.search(update_regex, download_file_content)
if not compose_version or not download_version:
print("Warning: Could not extract version from one or both files.")
return
# Compare versions
if compose_version.group(1) == download_version.group(1):
print("Versions are equal.")
return
print(f"Current version: {compose_version.group(1)}")
print(f"New version: {download_version.group(1)}")
# Show diff if requested or ask for confirmation
if show_diff:
if input("Update (will show diffs first)? (y/n): ").lower() != 'y':
return
print("\n")
for line in difflib.unified_diff(
compose_file_content.splitlines(), download_file_content.splitlines(), fromfile='Original',
tofile='Updated', lineterm=''):
print(line)
if input("Update? (y/n): ").lower() != 'y':
return
else:
if input("Update? (y/n): ").lower() != 'y':
return
print("\n")
# Backup compose file
shutil.copy2(compose_file_path, backup_file_path)
# Update compose file
with open(compose_file_path, 'w') as f:
f.write(download_file_content)
# Check if environment file path is set and adjust env_version_variable if needed
if env_file_path!="":
if(os.path.exists(env_file_path)):
with open(env_file_path, "r") as f:
env_content = f.read()
# Check if the "env_version_variable" line is present
if not any(line.startswith(f"{env_version_variable}=") for line in env_content.splitlines()):
print(f"Error: Variable '{env_version_variable}' is not defined in '{env_file_path}'. Exiting.")
return
# Check the value assigned to "env_version_variable"
for line in env_content.splitlines():
if line.startswith(f"{env_version_variable}="):
current_value = line.split("=", 1)[1]
if current_value != compose_version.group(1):
print(f"Warning: Expected {compose_version.group(1)}, but found '{current_value}' in '{env_file_path}'. Still updating.")
break # Stop after finding the variable
# Update the value in the environment file
with open(env_file_path, "w") as f:
for line in env_content.splitlines():
if line.startswith(f"{env_version_variable}="):
f.write(f"{env_version_variable}={download_version.group(1)}\n")
else:
f.write(line + "\n")
else:
print(f"Warning: Environment file '{env_file_path}' not found.")
print("Update complete.")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Update file based on version')
parser.add_argument('--download_path', type=str, default='https://raw.githubusercontent.com/example/docker-compose/main/docker-compose.yml')
parser.add_argument('--compose_file_path', type=str, default='./docker-compose.yml')
parser.add_argument('--backup_file_path', type=str, default='./docker-compose.yml.bck')
parser.add_argument('--update_regex', type=str, default=r'image: [\w.\-/]*:([\w.\-/]*)')
parser.add_argument('--show-diff', action="store_true", help="Show the difference between files after update", default=True)
parser.add_argument("--env_file_path", type=str, help="Path to the environment file", default="")
parser.add_argument("--env_version_variable", type=str, help="The variable name in the environment file to update", default="version")
args = parser.parse_args()
update_file(
args.download_path,
args.compose_file_path,
args.backup_file_path,
args.update_regex,
args.env_file_path,
args.env_version_variable,
show_diff=args.show_diff,
)