Skip to content
This repository was archived by the owner on Aug 7, 2024. It is now read-only.

Commit ee02022

Browse files
authored
Write setup script linux (#825)
* Mac setup created structure of the setup for mac has been implemented, now it just needs debugging and testing to make sure it works. * Script fixes fixed some issues surround certain command within the mac setup not working. These should have been fixed now. * added Documentation added comments and documentation for the script and it's functions, along with some warnings about use. * pep8 * Minor fix to yarn command added a new way of doing the frontend dependencies part of the setup that should solve the unreliability issue. * pep8++ * pep8++ * Structured linux setup script & minor changes to mac script written the structure of the linux/ubuntu setup script. There are some additional checks that need to be implemented at some point, like checking if they're using something other than an AMD or intel cpu. * Testing on Linux & minor-ish changes. * Minor changes finished the changes needed from the testing on linux. The script now installs aimmo on ubuntu, in future this may needed to be expanded to cover other linux distributions. But for now this is fine. * Minor changes++ * pep8 * pep8++ with small refactor code has been refactored to hopefully make it easier to understand and to resolve pep8 issues. * grammar fix in prints * Major refactor After some discussion and some pep8 related warnings, i went for a major refactor of the script in terms of it's structure to make it less complex, and hopefully further improve readability. * More refactor changes * pep8 * Minor changes * Minor fix fixed nodejs not always working * Fixed dpkg-query not working * Fixed get_nodejs() * Removed redundant code and minor fixes * minor changes * Minor changes + spelling corrections. * Whitespace + grammar
1 parent 714ca78 commit ee02022

File tree

1 file changed

+333
-0
lines changed

1 file changed

+333
-0
lines changed

aimmo_setup.py

Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
import platform
2+
import subprocess
3+
import traceback
4+
5+
from subprocess import PIPE, CalledProcessError
6+
7+
8+
# First we find and store the OS we are currently on, 0 if we didn't figure out which one
9+
hostOS = 0
10+
OStypes = {
11+
"mac": 1,
12+
"windows": 2,
13+
"linux": 3
14+
}
15+
valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False}
16+
17+
18+
def _cmd(command):
19+
'''
20+
:param command: command/subprocess to be run, as a string.
21+
22+
Takes in a command/subprocess, and runs it as if you would
23+
inside a terminal. DO NOT USE outside of the AI:MMO-setup script, and DO NOT INCLUDE
24+
in any release build, as this function is able to run bash scripts, and can run commands
25+
with sudo if specified.
26+
'''
27+
28+
p = subprocess.Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
29+
(_, _) = p.communicate()
30+
31+
if p.returncode != 0:
32+
raise CalledProcessError
33+
34+
35+
def install_yarn(operatingSystem):
36+
'''
37+
:param operatingSystem: values from the OStypes dict. (Should be updated to enum once python 3 is available)
38+
39+
OS dependant, so it must be passed to this function in order to run correctly.
40+
'''
41+
print('Installing Yarn...')
42+
if operatingSystem == OStypes['mac']:
43+
_cmd('brew install yarn')
44+
elif operatingSystem == OStypes['linux']:
45+
_cmd('sudo apt-get install yarn')
46+
elif operatingSystem == OStypes['windows']:
47+
pass
48+
else:
49+
raise Exception
50+
51+
52+
def install_pipenv(operatingSystem):
53+
'''
54+
:param operatingSystem: values from the OStypes dict. (Should be updated to enum once python 3 is available)
55+
56+
OS dependant, so it must be passed to this function in order to run correctly.
57+
'''
58+
print('Installing pipenv...')
59+
if operatingSystem == OStypes['mac']:
60+
_cmd('brew install pipenv')
61+
elif operatingSystem == OStypes['linux']:
62+
_cmd('pip install pipenv')
63+
elif operatingSystem == OStypes['windows']:
64+
pass
65+
else:
66+
raise Exception
67+
68+
69+
def install_docker(operatingSystem):
70+
'''
71+
:param operatingSystem: values from the OStypes dict. (Should be updated to enum once python 3 is available)
72+
73+
OS dependant, so it must be passed to this function in order to run correctly.
74+
'''
75+
print('Installing Docker...')
76+
if operatingSystem == OStypes['mac']:
77+
_cmd('brew cask install docker')
78+
elif operatingSystem == OStypes['linux']:
79+
_cmd('sudo apt-get install docker-ce')
80+
elif operatingSystem == OStypes['windows']:
81+
pass
82+
else:
83+
raise Exception
84+
85+
86+
def install_virtualbox(operatingSystem):
87+
'''
88+
:param operatingSystem: values from the OStypes dict. (Should be updated to enum once python 3 is available)
89+
90+
OS dependant, so it must be passed to this function in order to run correctly.
91+
'''
92+
print('Installing Virtualbox...')
93+
if operatingSystem == OStypes['mac']:
94+
_cmd('brew cask install virtualbox')
95+
elif operatingSystem == OStypes['linux']:
96+
_cmd('sudo apt-get install virtualbox')
97+
elif operatingSystem == OStypes['windows']:
98+
pass
99+
else:
100+
raise Exception
101+
102+
103+
def install_minikube(operatingSystem):
104+
'''
105+
:param operatingSystem: values from the OStypes dict. (Should be updated to enum once python 3 is available)
106+
107+
OS dependant, so it must be passed to this function in order to run correctly.
108+
'''
109+
print('Installing minikube...') # If minikube version changes this will need updating
110+
if operatingSystem == OStypes['mac']:
111+
_cmd('curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.25.2/minikube-darwin-amd64')
112+
_cmd('chmod +x minikube')
113+
_cmd('sudo mv minikube /usr/local/bin/')
114+
elif operatingSystem == OStypes['linux']:
115+
_cmd('curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.25.2/minikube-linux-amd64')
116+
_cmd('chmod +x minikube')
117+
_cmd('sudo mv minikube /usr/local/bin/')
118+
elif operatingSystem == OStypes['windows']:
119+
pass
120+
else:
121+
raise Exception
122+
123+
124+
def install_kurbernetes(operatingSystem):
125+
'''
126+
:param operatingSystem: values from the OStypes dict. (Should be updated to enum once python 3 is available)
127+
128+
OS dependant, so it must be passed to this function in order to run correctly.
129+
'''
130+
print('Installing Kubernetes...') # If kubernetes version changes this will need updating
131+
if operatingSystem == OStypes['mac']:
132+
_cmd('curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.9.4/bin/darwin/amd64/kubectl')
133+
_cmd('chmod +x kubectl')
134+
_cmd('sudo mv kubectl /usr/local/bin/')
135+
elif operatingSystem == OStypes['linux']:
136+
_cmd('sudo snap install kubectl --classic')
137+
elif operatingSystem == OStypes['windows']:
138+
pass
139+
else:
140+
raise Exception
141+
142+
143+
def install_pip(): # Linux only
144+
print('Installing pip...')
145+
_cmd('sudo apt-get install python-pip')
146+
147+
148+
def install_snap(): # Linux only
149+
print('Installing snap...')
150+
_cmd('sudo apt install snapd')
151+
152+
153+
def install_nodejs(): # Linux only
154+
print('Installing Nodejs...')
155+
_cmd('sudo apt-get install -y nodejs')
156+
157+
158+
def run_pipenv_install(): # OS independent
159+
print('Running "pipenv install"...')
160+
_cmd('pipenv install')
161+
162+
163+
def set_up_frontend_dependencies(): # Mac & Linux only
164+
print('Setting up frontend dependencies...')
165+
_cmd('cd ./game_frontend | sudo yarn')
166+
167+
168+
def check_homebrew(): # Mac only
169+
_cmd('brew -v')
170+
print('Homebrew Found...')
171+
172+
173+
def check_for_cmdtest(): # Linux/Ubuntu only
174+
'''
175+
This function is for use within the Linux setup section of the script. It checks if
176+
the cmdtest package is installed, if it is we ask the user if we can remove it, if yes
177+
we remove the package, if not the process continues without removing it.
178+
'''
179+
p = subprocess.Popen("dpkg-query -W -f='${status}' cmdtest", shell=True, stdout=PIPE)
180+
(stdout, _) = p.communicate()
181+
if 'unknown' not in stdout:
182+
print('Looks like cmdtest is installed on your machine, this can cause issues when installing Yarn.')
183+
184+
answer = False
185+
answered = False
186+
while not answered:
187+
choice = raw_input('Is it okay if I remove cmdtest? [y/n]').lower()
188+
if choice in valid:
189+
answer = valid[choice]
190+
answered = True
191+
else:
192+
print("Please answer 'yes' or 'no' ('y' or 'n').")
193+
if answer:
194+
print('Removing cmdtest...')
195+
_cmd('apt-get remove cmdtest')
196+
else:
197+
print('Continuing without removing cmdtest...')
198+
199+
200+
def update_apt_get(): # Linux only
201+
print('Updating apt-get...')
202+
_cmd('sudo apt-get update')
203+
204+
205+
def get_nodejs(): # Linux only
206+
print('Getting Nodejs...')
207+
_cmd('curl python-software-properties | sudo apt-get install')
208+
_cmd('curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -')
209+
210+
211+
def add_aimmo_to_hosts_file(): # Mac & Linux only
212+
with open("/etc/hosts", "r") as hostfile:
213+
data = hostfile.read().replace('\n', '')
214+
if "192.168.99.100 local.AI:MMO.codeforlife.education" not in data:
215+
print('Adding AI:MMO to /etc/hosts...')
216+
_cmd("sudo sh -c 'echo 192.168.99.100 local.aimmo.codeforlife.education >> /etc/hosts'")
217+
else:
218+
print('AI:MMO already present in /etc/hosts...')
219+
220+
221+
def add_parcel_bundler(): # Mac & Linux only
222+
print('Adding parcel-bundler globally...')
223+
_cmd('yarn global add parcel-bundler')
224+
225+
226+
def configure_yarn_repo(): # Linux only
227+
print('Configuring Yarn repository...')
228+
_cmd('curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -')
229+
_cmd('echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list')
230+
231+
232+
def mac_setup(hostOS):
233+
'''
234+
Runs the list of commands, sequentially, needed in order to set up AI:MMO for a Mac.
235+
After this has been run the user needs to open Docker to finalise its install,
236+
and get the unity package for AI:MMO from AI:MMO-unity.
237+
'''
238+
try:
239+
check_homebrew()
240+
install_yarn(hostOS)
241+
add_parcel_bundler()
242+
set_up_frontend_dependencies()
243+
install_pipenv(hostOS)
244+
run_pipenv_install()
245+
install_docker(hostOS)
246+
install_virtualbox(hostOS)
247+
install_minikube(hostOS)
248+
install_kurbernetes(hostOS)
249+
250+
print('---------------------------------------------------------------------------------------------------')
251+
print("| You now need to get the unity package from the AI:MMO-unity repo, place its contents |")
252+
print('| in aimmo/aimmo/static/unity. (folder may not exist yet) |')
253+
print('| You may also need to open docker, just to finalise the install. |')
254+
print('---------------------------------------------------------------------------------------------------')
255+
print('| Everything should now be ready for you to use AI:MMO! :D |')
256+
print('---------------------------------------------------------------------------------------------------')
257+
258+
except CalledProcessError as e:
259+
print('A command has return an exit code != 0, so something has gone wrong.')
260+
traceback.print_exc()
261+
except OSError as e:
262+
print("Tried to execute a command that didn't exist.")
263+
traceback.print_exc()
264+
except ValueError as e:
265+
print('Tried to execute a command with invalid arguments.')
266+
traceback.print_exc()
267+
except Exception as e:
268+
print("Something went very wrong, maybe I couldn't read hosts? otherwise I have no idea what it was D:")
269+
traceback.print_exc()
270+
271+
272+
def windows_setup(hostOS):
273+
pass
274+
275+
276+
def linux_setup(hostOS):
277+
try:
278+
update_apt_get()
279+
get_nodejs()
280+
install_nodejs()
281+
check_for_cmdtest()
282+
configure_yarn_repo()
283+
install_yarn(hostOS)
284+
add_parcel_bundler()
285+
install_pip()
286+
install_pipenv(hostOS)
287+
set_up_frontend_dependencies()
288+
install_kurbernetes(hostOS)
289+
install_docker(hostOS)
290+
add_aimmo_to_hosts_file()
291+
292+
print('---------------------------------------------------------------------------------------------------')
293+
print("| You now need to get the unity package from the AI:MMO-unity repo, place its contents |")
294+
print('| in aimmo/aimmo/static/unity (folder may not exist yet) |')
295+
print('---------------------------------------------------------------------------------------------------')
296+
print('| Everything should now be ready for you to use AI:MMO! :D |')
297+
print('---------------------------------------------------------------------------------------------------')
298+
299+
except CalledProcessError as e:
300+
print('Command returned an exit code != 0, so something has gone wrong.')
301+
traceback.print_exc()
302+
except OSError as e:
303+
print("Tried to execute a command that didn't exist.")
304+
traceback.print_exc()
305+
except ValueError as e:
306+
print('Tried to execute a command with invalid arguments')
307+
traceback.print_exc()
308+
except Exception as e:
309+
print("Something went very wrong, maybe I couldn't read hosts? otherwise I have no idea what it was D:")
310+
traceback.print_exc()
311+
312+
313+
print('---------------------------------------------------------------------------------------------------')
314+
print('| Welcome to AI:MMO! This script should make your life a little easier, |')
315+
print("| just be kind if it doesn't work. |")
316+
print('| You may be asked to enter your password during this setup. |')
317+
print('---------------------------------------------------------------------------------------------------')
318+
319+
if platform.system() == 'Darwin':
320+
hostOS = OStypes["mac"]
321+
print('MAC found!')
322+
mac_setup(hostOS)
323+
elif platform.system() == 'Windows':
324+
hostOS = OStypes["windows"]
325+
print('WINDOWS found!')
326+
windows_setup(hostOS)
327+
elif platform.system() == 'Linux':
328+
hostOS = OStypes["linux"]
329+
print('LINUX found!')
330+
linux_setup(hostOS)
331+
else:
332+
print("Could not detect operating system. Maybe you're using")
333+
print('something other than Windows, Mac, or Linux?')

0 commit comments

Comments
 (0)