-
Notifications
You must be signed in to change notification settings - Fork 1
/
install.sh
executable file
·373 lines (313 loc) · 18 KB
/
install.sh
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
#!/bin/bash
BOT="[samf-bot]"
# "$?" references return code from last command.
### Imports ###
echo ; echo ; echo ; echo "================================================================================================================"
[ -f bash_utils.sh ] && echo "$BOT: Don't mind me, I'm just sourcing 'bash_utils.sh'" && . bash_utils.sh
[ -f ~/.bash_profile ] && echo "$BOT: Don't mind me, I'm just sourcing '~/.bash_profile'" && . ~/.bash_profile
### End: Imports ###
# Initialise global 'X_INTERACTIVE'. Defaults to "y".
echo ; echo ; echo ; echo "================================================================================================================"
X_INTERACTIVE=${X_INTERACTIVE:="y"}
echo "$BOT: Running script in interaction mode: '$X_INTERACTIVE'"
### Welcome ###
echo ; echo ; echo ; echo "================================================================================================================"
echo
echo "$BOT:"
echo " Hi, and welcome to Samfundet!"
echo
echo " I will provide everything you need to clone, build, and run the project."
echo
echo " I am partly interactive and will at some point depend on manual input from you to complete the installation."
echo " (These steps consists of first time setup of ssh keys etc...)"
echo
echo " If you know that you have already configured what is asked of you, "
echo " you may skip the step (no need to remember, I will mention it again)."
echo
if [ "$X_INTERACTIVE" == "y" ]; then
echo " I will prompt for permission before performing any action,"
echo " although most of them are neccessary to complete the script."
echo
echo " Questions annotated with (required) must run to succeed successfully."
fi
echo
do_action "\"I understand\"" "echo '$BOT: Here we go!'; sleep 1;" "y" || eval "echo \"$BOT: That's okay, I can't read either 😔. I'll let you off the hook for now...\"; sleep 1; exit 1"
### End: Welcome ###
### Requirements ###
# OS
[[ "$OSTYPE" == "darwin"* ]] ; IS_MAC=$?
[[ "$OSTYPE" == "linux-gnu"* ]] ; IS_UBUNTU=$?
# Attempt to install requirements first.
# https://github.com/pyenv/pyenv/wiki#suggested-build-environment
echo ; echo ; echo ; echo "================================================================================================================"
if [ $IS_UBUNTU == 0 ]; then
do_action "$BOT: Attempt to install requirements (build-essential, procps, curl, file, git, ssh)" "sudo apt update -y ; sudo apt upgrade -y ; sudo apt install -y build-essential procps curl file git ssh" "$X_INTERACTIVE"
elif [ $IS_MAC == 0 ]; then
do_action "$BOT: Attempt to install requirements (curl, git)" "brew install git curl" "$X_INTERACTIVE"
do_action "$BOT: Install xcode-select" "xcode-select --install" "$X_INTERACTIVE"
fi
# Fail if missing requirements.
require "git"
require "curl"
require "ssh"
require "file"
require "ps" # procps
### End: requirements ###
### brew ###
# Install brew if it doesn't exist.
if [ ! "$(which brew)" ]; then
echo ; echo ; echo ; echo "================================================================================================================"
echo "Homebrew is a packet manager such as 'apt' for Linux."
do_action "$BOT: Install Homebrew (required)?" "" "$X_INTERACTIVE"
if [ "$?" == 0 ]; then
# Non-X_INTERACTIVE install.
NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Update PATH and current shell.
# Must be wrapped by single quotes.
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> "$HOME"/.bash_profile
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
fi
fi
# Update and upgrade brew if it exists.
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Update and upgrade Homebrew (required)?" "" "$X_INTERACTIVE"
if [ "$?" == 0 ] && [ "$(which brew)" ]; then
# Update brew.
echo "Updating and upgrading brew:"
brew update && brew upgrade && brew upgrade --cask
echo ; echo "Installing gcc"
brew install gcc # Recommended by brew.
fi
### docker ###
if [[ ! "$(docker compose)" ]]; then
echo ; echo ; echo ; echo "================================================================================================================"
if [ $IS_UBUNTU == 0 ]; then
do_action "$BOT: Install docker (required)?" "" "$X_INTERACTIVE"
if [ "$?" == 0 ]; then
# https://docs.docker.com/engine/install/ubuntu/
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
fi
elif [ $IS_MAC == 0 ]; then
do_action "$BOT: Install docker (required)?" "brew install docker docker-compose; mkdir -p ~/.docker/cli-plugins; ln -sfn /usr/local/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose" "$X_INTERACTIVE"
fi
fi
### colima ###
# Replacement for docker-desktop. Only needed for MacOS.
# https://github.com/abiosoft/colima
if [ ! "$(which colima)" ] && [ $IS_MAC == 0 ]; then
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Install colima (required unless you have docker-desktop)?" "brew install colima && colima start" "$X_INTERACTIVE"
fi
### bash-completion ###
# echo ; echo ; echo ; echo "================================================================================================================"
# do_action "$BOT: Install bash-completion (recommended)?" "brew install bash-completion" $X_INTERACTIVE
### jq ###
if [ ! "$(which jq)" ]; then
echo ; echo ; echo ; echo "================================================================================================================"
echo "Json parser."
echo "Used to parse extensions.json for VSCode setup."
if [ $IS_UBUNTU == 0 ]; then
do_action "$BOT: Install jq (optional)?" "sudo apt install -y jq" "$X_INTERACTIVE"
elif [ $IS_MAC == 0 ]; then
do_action "$BOT: Install jq (optional)?" "brew install jq" "$X_INTERACTIVE"
fi
fi
### postgresql ###
if [ ! "$(which psql)" ]; then
echo ; echo ; echo ; echo "================================================================================================================"
if [ $IS_UBUNTU == 0 ]; then
do_action "$BOT: Install postgresql (required)?" "sudo apt install -y postgresql libpq-dev && sudo service postgresql restart" "$X_INTERACTIVE"
elif [ $IS_MAC == 0 ]; then
do_action "$BOT: Install postgresql (required)?" "brew install postgresql && brew services restart postgresql" "$X_INTERACTIVE"
fi
fi
### pyenv ###
if [ ! "$(which pyenv)" ]; then
echo ; echo ; echo ; echo "================================================================================================================"
# do_action "$BOT: Install pyenv (required)?" "brew install pyenv ; echo 'export PYENV_ROOT=~/.pyenv' >> ~/.bash_profile && echo 'export PATH=~/.pyenv/bin:$PATH' >> ~/.bash_profile ; echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval '$(pyenv init -)'\nfi' >> ~/.bash_profile ; . ~/.bash_profile" $X_INTERACTIVE
# https://github.com/pyenv/pyenv/wiki#suggested-build-environment
do_action "$BOT: Install pyenv (required)?" "" "$X_INTERACTIVE"
if [ "$?" == 0 ] ; then # If 'yes'.
# Install pyenv dependencies to OS.
if [ $IS_UBUNTU ] ; then
sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
elif [ $IS_MAC ] ; then
brew install openssl readline sqlite3 xz zlib tcl-tk
fi
# Install pyenv.
brew install pyenv
# Must be wrapped by single quotes.
echo 'export PYENV_ROOT=~/.pyenv' >> ~/.bash_profile
echo 'export PATH=~/.pyenv/bin:$PATH' >> ~/.bash_profile
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
. ~/.bash_profile
fi
fi
### github-cli ###
if [ ! "$(which gh)" ]; then
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Install github-cli (gh) (required)?" "brew install gh" "$X_INTERACTIVE"
fi
### Offer to install applications to MacOS ###
if [ $IS_MAC == 0 ]; then
# Cask packages are MacOS only.
### google-chrome ###
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Install google-chrome (optional)?" "brew install --cask google-chrome" "y"
### iterm2 ###
echo ; echo ; echo ; echo "================================================================================================================"
echo "Iterm2 is an improved version of Terminal."
do_action "$BOT: Install iterm2 (optional)?" "brew install --cask iterm2" "y"
### visual-studio-code ###
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Install visual-studio-code (optional)?" "brew install visual-studio-code" "y"
### alt-tab ###
# Enables tabbing similar to Windows.
# https://alt-tab-macos.netlify.app/
echo ; echo ; echo ; echo "================================================================================================================"
echo ; echo ; echo "AltTab is an application that provides a tabbing experience similar to Windows."
do_action "$BOT: Install alt-tab (optional)?" "brew install --cask alt-tab" "y"
fi
### Setup project ###
if [ "$(which gh)" ]; then
echo ; echo ; echo ; echo "================================================================================================================"
echo "Make a PAT (Personal Access Token) here: https://github.com/settings/tokens/new"
echo "Select scopes (repo, read:org, admin:public_key)."
echo "This token is important. Store it someplace safe, preferably a password manager (github will never show it again)."
echo
do_action "$BOT: I have created (or already have) a PAT." "" "$X_INTERACTIVE"
# Get email.
# echo ; echo ; echo ; echo "================================================================================================================"
# get_var_with_confirm "EMAIL" "Email at github.com: "
# Create ssh key.
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Do you wish to create a new ssh key?" "" "y"
if [ "$?" == 0 ]; then
get_var_with_confirm "EMAIL" "Email at github.com: "
ssh-keygen -t ed25519 -C "$EMAIL"
fi
# Get private ssh key to use further.
# echo ; echo ; echo ; echo "================================================================================================================"
# shopt -s extglob # Enable enhanced globbing.
# ls ~/.ssh/!(*.pub) # Show all private keys to user.
# ls -lad ~/.ssh/*
# get_var_with_confirm "KEY_PRIV" "Please give me the path to a PRIVATE ssh key: "
# Add ssh key to github.
echo ; echo ; echo ; echo "================================================================================================================"
# Github will ask to add ssh-key on authentication.
echo "You should skip if you have done this step before."
echo "If you generate/add ssh key, select SSH as preferred method, then use PAT to authenticate."
do_action "$BOT: Add ssh key to your Github account?" "gh auth login" "y"
# Add ssh key to ~/ssh/config.
echo ; echo ; echo ; echo "================================================================================================================"
echo "You should skip if you have done this step before."
do_action "$BOT: Add an ssh key to ~/.ssh/config with host (github.com)?" "echo 'I have listed the content in ~/.ssh for you:'; ls -lad ~/.ssh/*" "y"
if [ "$?" == 0 ]; then
get_var_with_confirm "KEY_PRIV" "Please give me the path to a PRIVATE ssh key: "
echo $'\nHost github.com\n\tPreferredauthentications publickey\n\tIdentityFile '"$KEY_PRIV" >> ~/.ssh/config
fi
# Start ssh-agent.
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Start ssh-agent (required)?" "echo 'I have listed the content in ~/.ssh for you:'; ls -lad ~/.ssh/*" "y"
if [ "$?" == 0 ]; then
get_var_with_confirm "KEY_PRIV" "Please give me the path to a PRIVATE ssh key: "
# chmod 600 $KEY_PRIV # Only accessible to you.
eval "$(ssh-agent -s)" # Start ssh-agent.
ssh-add "$KEY_PRIV" # Add key to ssh-agent session.
# echo $'\neval "$(ssh-agent -s)" # Start ssh-agent.\nssh-add '$KEY_PRIV$' # Add key to ssh-agent session.\n' >> ~/.bash_profile
# . ~/.bash_profile
fi
fi
# Clone project.
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Clone repo git@github.com:Samfundet/Samfundet4.git?" "git clone git@github.com:Samfundet/Samfundet4.git" "$X_INTERACTIVE"
### Setup project if cloned. ###
if [ "$(ls Samfundet4/README.md)" ] ; then # Simple check if an arbitrary file exists.
# Some extra steps.
cd Samfundet4 || exit
cp .env.example .env
cp backend/.env.example backend/.env
cp backend/.docker.example.env backend/.docker.env
cp frontend/.env.local.example frontend/.env.local
cp frontend/.env.docker.example frontend/.env.docker
cp .vscode/settings.default.json .vscode/settings.json
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Do you wish to configure VSCode?" "" "$X_INTERACTIVE"
if [ "$?" == 0 ] ; then
echo "VSCode setup (requires that you cloned the project):"
echo
echo "1. Open VSCode"
echo "2. Press CMD+Shift+P"
echo "3. Type 'install code'"
echo "4. Select the alternative 'Shell Command: Install 'code' command in PATH' "
echo
do_action "$BOT: When this is finished, confirm to continue..." "" "$X_INTERACTIVE"
# Install default extensions.
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Install default vscode extensions from .vscode/extensions.json?" "install_extensions .vscode/extensions.json" "$X_INTERACTIVE"
# Install recommended extensions.
# echo ; echo ; echo ; echo "================================================================================================================"
# do_action "$BOT: Install recommended vscode extensions from .vscode/extensions.json.recommended?" "install_extensions .vscode/extensions.json.recommended" $X_INTERACTIVE
fi
# Install python virtual environment with dependencies.
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Install virtual python environment (pyenv, poetry)?" "pyenv install ; python -m pip install poetry ; POETRY_VIRTUALENVS_IN_PROJECT=1 python -m poetry install --python $(cat backend/.python-version)" "$X_INTERACTIVE"
# Build project.
echo ; echo ; echo ; echo "================================================================================================================"
do_action "$BOT: Build project?" "" "$X_INTERACTIVE"
if [ "$?" == 0 ]; then
if [ $IS_UBUNTU == 0 ]; then
sudo docker compose build
elif [ $IS_MAC == 0 ]; then
docker compose build # Mac doesn't need to use sudo.
fi
fi
fi
### Cleanup ###
unset X_INTERACTIVE
unset EMAIL
unset KEY_PRIV
### Final messages ###
echo ; echo ; echo ; echo "================================================================================================================"
echo
cat << EOF
_ _ _ _
/\ | | | | | | |
/ \ | | | __| | ___ _ __ ___| |
/ /\ \ | | | / _' |/ _ \| '_ \ / _ \ |
/ ____ \| | | | (_| | (_) | | | | __/_|
/_/ \_\_|_| \__,_|\___/|_| |_|\___(_)
EOF
echo
echo "Remember to configure environment settings in file '.env'"
echo
echo "You can now run this command to start the project in a docker container:"
# echo " docker build -t samfundet/Samfundet4 . && docker run --rm --name samfundet-Samfundet4 -p 8000:8000 -it samfundet/Samfundet4"
echo " $ docker compose up"
echo
echo "NOTE: See Dockerfile for more useful commands."
echo
do_action "$BOT: I can also start the project if you'd like" "" "y"
if [ "$?" == 0 ]; then
if [ $IS_UBUNTU == 0 ]; then
sudo docker compose up
elif [ $IS_MAC == 0 ]; then
# Mac doesn't need to use sudo.
docker compose up
fi
fi
# echo "You can now run these commands to start the project:"
# echo " python -m poetry run python manage.py collectstatic"
# echo " python -m poetry run python manage.py migrate"
# echo " python -m poetry run python manage.py runserver"