-
Notifications
You must be signed in to change notification settings - Fork 0
/
unchained.py
139 lines (120 loc) · 6.24 KB
/
unchained.py
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
import os, subprocess
class Creator():
s_DefaultAppName = "app"
s_DefaultImage = "python:3.9-alpine"
s_DefaultTag = ""
s_DefaultComposeVersion = "3.7"
s_DefaultModuleName = "module"
def __init__(self):
# First we need to get the user input for what the app will be called
self.setInputs()
# Store the working directory of this program
self.s_cwd = os.getcwd()
self.createRequirements()
# We need to create a Django project (named by user) located in our current directory
self.createDjangoProject()
# We also need to create a Dockerfile
self.createDockerfile()
# and finally a docker-compose file
self.createDockerCompose()
def setInputs(self):
s_NameInput = input(f"Enter the name for your app (leave blank for '{self.s_DefaultAppName}'): ")
if s_NameInput == "":
print(f"\tNo input provided, using default app name: '{self.s_DefaultAppName}'")
self.s_AppName = self.s_DefaultAppName
else:
self.cleanNameInput(s_NameInput)
s_TagInput = input(f"Do you have a special tag for this container? (leave blank if not): ")
if s_TagInput == "":
print(f"\tNo input provided, using default tag name: '{self.s_DefaultTag}'")
self.s_TagName = self.s_DefaultTag
else:
self.s_TagName = s_TagInput
s_ImageInput = input(f"Do you have a special Docker image for this project? (leave blank for {self.s_DefaultImage}): ")
if s_ImageInput == "":
print(f"\tNo input provided, using default image: '{self.s_DefaultImage}'")
self.s_Image = self.s_DefaultImage
else:
self.s_Image = s_ImageInput
s_ComposeVersionInput = input(f"Do you have a special compose version for this project? (leave blank for {self.s_DefaultComposeVersion}): ")
if s_ComposeVersionInput == "":
print(f"\tNo input provided, using default compose version: '{self.s_DefaultComposeVersion}'")
self.s_ComposeVersion = self.s_DefaultComposeVersion
else:
self.s_ComposeVersion = self.s_ComposeVersionInput
def cleanNameInput(self, s_NameInput):
print(f"Checking if {s_NameInput} is a valid app name...")
if s_NameInput.isalpha():
self.s_AppName = s_NameInput
print(f"\t{s_NameInput} is valid, using app name: '{self.s_AppName}'")
return
else:
raise ValueError(f"\napp name must only contain letters, you have provided: {s_NameInput}")
def createDjangoProject(self):
s_BashCommand = f"mkdir ./output/{self.s_AppName}"
a_BashCommand = s_BashCommand.split()
process = subprocess.Popen(a_BashCommand, stdout=subprocess.PIPE)
output, error = process.communicate()
s_BashCommand = f"django-admin startproject {self.s_AppName} ./output/{self.s_AppName}"
a_BashCommand = s_BashCommand.split()
process = subprocess.Popen(a_BashCommand, stdout=subprocess.PIPE)
output, error = process.communicate()
def createRequirements(self):
# Create the requirements file
f_Requirements = open("./output/requirements.txt", "w")
f_Requirements.write("Django==3.1.3")
f_Requirements.close()
def createDockerfile(self):
# Create the dockerfile, append lines to it one at a time
f_Dockerfile = open("./output/Dockerfile", "w")
# This line is where we import our base image from
f_Dockerfile.write(f"FROM {self.s_Image}\n")
# In our base image, enter a new folder, app
f_Dockerfile.write(f"WORKDIR /app/\n")
# Copy our requirements file to be installed in our container
f_Dockerfile.write(f"COPY ./requirements.txt ./requirements.txt\n")
# Temporarily install anything we need for our requirements.txt install
f_Dockerfile.write(f"RUN apk add --update --no-cache --virtual .tmp gcc libc-dev linux-headers\n")
# Install what is specified in requirements.txt
f_Dockerfile.write(f"RUN pip install -r ./requirements.txt\n")
# Delete all the temporary tools we needed
f_Dockerfile.write(f"RUN apk del .tmp\n")
# Copy our data from host to container
f_Dockerfile.write(f"COPY ./{self.s_AppName} ./\n")
# Command to be executed
f_Dockerfile.write(f"CMD [\"python\", \"{self.s_AppName}/manage.py\", \"runserver\", \"0.0.0.0:8000\"]")
# Close the file
f_Dockerfile.close()
def createDockerCompose(self):
# Create the docker-compose.yml file
f_DockerComposefile = open("./output/docker-compose.yml", "w")
# Set the version to the number provided by the user
f_DockerComposefile.write(f"version: '{self.s_ComposeVersion}'\n")
# Define our services
f_DockerComposefile.write(f"services:\n")
# Start with our app
f_DockerComposefile.write(f" app:\n")
# Outline the build
f_DockerComposefile.write(f" build:\n")
# Locate where the Dockerfile will be (. is current directory)
f_DockerComposefile.write(f" context: .\n")
# Connect our container ports to our host ports
f_DockerComposefile.write(f" ports:\n")
# Specifically, connect our 8000 port to 8000
f_DockerComposefile.write(f" - \"8000:8000\"\n")
# Define our shared volumes
f_DockerComposefile.write(f" volumes:\n")
f_DockerComposefile.write(f" - ./{self.s_AppName}:/{self.s_AppName}\n")
# The closing command
f_DockerComposefile.write(f" command: sh -c \"python manage.py runserver 0.0.0.0:8000\"\n")
f_DockerComposefile.write(f" environment:\n")
f_DockerComposefile.write(f" - DEBUG=1\n")
f_DockerComposefile.write(f"\n")
f_DockerComposefile.write(f"volumes:\n")
f_DockerComposefile.write(f" shared:\n")
f_DockerComposefile.write(f" {self.s_AppName}:")
f_DockerComposefile.close()
def main():
o_Creator = Creator()
if __name__=="__main__":
main()