forked from divad12/khan-dotfiles
-
Notifications
You must be signed in to change notification settings - Fork 18
/
linux-setup.sh
executable file
·366 lines (310 loc) · 13.4 KB
/
linux-setup.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
#!/bin/sh
# This installs binaries that you need to develop at Khan Academy.
# The OS-independent setup.sh assumes all this stuff has been
# installed.
# Bail on any errors
set -e
# Install in $HOME by default, but can set an alternate destination via $1.
ROOT=${1-$HOME}
mkdir -p "$ROOT"
# the directory all repositories will be cloned to
REPOS_DIR="$ROOT/khan"
# derived path location constants
DEVTOOLS_DIR="$REPOS_DIR/devtools"
# Load shared setup functions.
. "$DEVTOOLS_DIR"/khan-dotfiles/shared-functions.sh
trap exit_warning EXIT # from shared-functions.sh
install_java() {
sudo apt-get install -y openjdk-11-jdk
# We ask you to select a java version (interactively) in case you have more
# than one installed. If there's only one, it'll just select that version
# by default.
sudo update-alternatives --config java
sudo update-alternatives --config javac
}
install_go() {
if ! has_recent_go; then # has_recent_go is from shared-functions.sh
# This PPA is needed for ubuntus <20 but not >=20
# (and it doesn't install for them anyway)
sudo add-apt-repository -y ppa:longsleep/golang-backports && sudo apt-get update -qq -y || sudo add-apt-repository -y -r ppa:longsleep/golang-backports
sudo apt-get install -y "golang-$DESIRED_GO_VERSION"
# The ppa installs go into /usr/lib/go-<version>/bin/go
# Let's link that to somewhere likely to be on $PATH
sudo cp -sf /usr/lib/"go-$DESIRED_GO_VERSION"/bin/* /usr/local/bin/
else
echo "golang already installed"
fi
}
# Builds and installs `mkcert` which is used by the following things in
# webapp:
# - https://khanacademy.dev
# - the "Vitejs Directly" option in the dev support bar
#
# NOTE: This depends on `go` being installed.
install_mkcert() {
if ! which mkcert >/dev/null; then
update "Installing mkcert..."
builddir=$(mktemp -d -t mkcert.XXXXX)
git clone https://github.com/FiloSottile/mkcert "$builddir"
(
cd "$builddir"
go mod download
go build -ldflags "-X main.Version=$(git describe --tags)"
sudo install -m 755 mkcert /usr/local/bin
)
# cleanup temporary build directory
rm -rf "$builddir"
mkcert -install
echo "You have installed mkcert (used to make khanacademy.dev and "
echo "'Vitejs Directly' on localhost:8088 work)."
echo ""
echo "A CA has been added to your system and browser certificate "
echo "trust stores."
echo ""
echo "You must RESTART your browser in order for it to recognize "
echo "the new CA and in some situations you may need REBOOT your "
echo "machine."
else
echo "mkcert already installed"
fi
}
# NOTE: if you add a package here, check if you should also add it
# to webapp's Dockerfile.
install_packages() {
updated_apt_repo=""
# This is needed to get the add-apt-repository command.
# apt-transport-https may not be strictly necessary, but can help
# for future updates.
sudo apt-get install -y software-properties-common apt-transport-https \
wget gnupg
# To get the most recent nodejs, later.
if ls /etc/apt/sources.list.d/ 2>&1 | grep -q chris-lea-node_js; then
# We used to use the (obsolete) chris-lea repo, remove that if needed
sudo add-apt-repository -y -r ppa:chris-lea/node.js
sudo rm -f /etc/apt/sources.list.d/chris-lea-node_js*
updated_apt_repo=yes
fi
if ! ls /etc/apt/sources.list.d/ 2>&1 | grep -q nodesource || \
! grep -q node_20.x /etc/apt/sources.list.d/nodesource.list; then
# This is a simplified version of https://deb.nodesource.com/setup_20.x
sudo mkdir -p /usr/share/keyrings
sudo rm -f /usr/share/keyrings/nodesource.gpg
sudo rm -f /etc/apt/sources.list.d/nodesource.list
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg
cat <<EOF | sudo tee /etc/apt/sources.list.d/nodesource.list
deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main
EOF
sudo chmod a+rX /etc/apt/sources.list.d/nodesource.list
# Pin nodejs to the version-specific nodesource repo, otherwise apt might update
# it in newer Ubuntu versions
cat <<EOF | sudo tee /etc/apt/preferences.d/nodejs
Package: nodejs
Pin: origin deb.nodesource.com
Pin-Priority: 999
EOF
updated_apt_repo=yes
fi
# To get the most recent git, later.
if ! ls /etc/apt/sources.list.d/ 2>&1 | grep -q git-core-ppa; then
sudo add-apt-repository -y ppa:git-core/ppa
updated_apt_repo=yes
fi
# To get the most recent python, later.
if ! ls /etc/apt/sources.list.d/ 2>&1 | grep -q deadsnakes; then
sudo add-apt-repository -y ppa:deadsnakes/ppa
updated_apt_repo=yes
fi
# To get chrome, later.
if [ ! -s /etc/apt/sources.list.d/google-chrome.list ]; then
wget -O- https://dl-ssl.google.com/linux/linux_signing_key.pub \
| sudo gpg --no-default-keyring --keyring /etc/apt/keyrings/google-chrome.gpg --import
echo 'deb [signed-by=/etc/apt/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main' \
| sudo tee /etc/apt/sources.list.d/google-chrome.list
updated_apt_repo=yes
fi
# Register all that stuff we just did.
if [ -n "$updated_apt_repo" ]; then
sudo apt-get update -qq -y || true
fi
# Python3 is needed to run the python services (e.g. ai-guide-core).
# We are on python3.11 now
sudo apt-get install -y python3.11 python3.11-venv
# Install curl for setup script usage
sudo apt-get install -y curl
# Needed to develop at Khan: git, node (js).
# lib{freetype6{,-dev},{png,jpeg}-dev} are needed for PIL
# imagemagick is needed for image resizing and other operations
# lib{xml2,xslt}-dev are needed for lxml
# libyaml-dev is needed for pyyaml
# libncurses-dev and libreadline-dev are needed for readline
# nodejs is used for various frontendy stuff in webapp, as well as our js
# services. We standardize on version 16.
# redis is needed to run memorystore on dev
# libnss3-tools is a pre-req for mkcert, see install_mkcert for details.
# python3-venv is needed for the deploy virtualenv
# cargo is needed to run fastly-khancademy-dev
# docker is needed to run dev/server, lsof and uuid-runtime to run hotel
# TODO(benkraft): Pull the version we want from webapp somehow.
sudo apt-get install -y git \
libfreetype6 libfreetype6-dev libpng-dev libjpeg-dev \
imagemagick \
libxslt1-dev \
libyaml-dev \
libncurses-dev libreadline-dev \
nodejs \
redis-server \
unzip \
jq \
libnss3-tools \
python3-dev python3-setuptools python3-pip python3-venv \
python-is-python3 \
cargo cargo-doc \
docker lsof uuid-runtime
# We need npm 8 or greater to support node16. That's the default
# for nodejs, but we may have overridden it before in a way that
# makes it impossible to upgrade, so we reinstall nodejs if our
# npm version is 5.x.x, 6.x.x, or 7.x.x.
if expr "`npm --version`" : '5\|6\|7' >/dev/null 2>&1; then
sudo apt-get purge -y nodejs
sudo apt-get install -y "nodejs"
fi
# Ubuntu installs as /usr/bin/nodejs but the rest of the world expects
# it to be `node`.
if ! [ -f /usr/bin/node ] && [ -f /usr/bin/nodejs ]; then
sudo ln -s /usr/bin/nodejs /usr/bin/node
fi
# Ubuntu's nodejs doesn't install npm, but if you get it from the PPA,
# it does (and conflicts with the separate npm package). So install it
# if and only if it hasn't been installed already.
if ! which npm >/dev/null 2>&1 ; then
sudo apt-get install -y npm
fi
# Make sure we have the preferred version of npm
# TODO(benkraft): Pull this version number from webapp somehow.
# We need npm 8 or greater to support node16. This is a particular npm8
# version known to work.
sudo npm install -g [email protected]
# Not technically needed to develop at Khan, but we assume you have it.
sudo apt-get install -y unrar ack-grep
# Not needed for Khan, but useful things to have.
sudo apt-get install -y ntp abiword diffstat expect gimp \
mplayer netcat iftop tcpflow netpbm screen w3m \
vim emacs google-chrome-stable
# If you don't have the other ack installed, ack is shorter than ack-grep
# This might fail if you already have ack installed, so let it fail silently.
sudo dpkg-divert --local --divert /usr/bin/ack --rename --add \
/usr/bin/ack-grep || echo "Using installed ack"
# Needed to install printer drivers, and to use the printer scanner
sudo apt-get install -y apparmor-utils xsane
# We use java for our google cloud dataflow jobs that live in webapp
# (as well as in khan-linter for linting those jobs)
install_java
# We use go for our code, going forward
install_go
# Used to create and install security certificates, see the docstring
# for this function for more details.
install_mkcert
}
install_protoc() {
# The linux and mac installation process is the same aside from the
# platform-dependent zip archive.
install_protoc_common https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-linux-x86_64.zip
}
install_watchman() {
if ! which watchman ; then
update "Installing watchman..."
# First try installing via apt package, which exists in the repositories
# as of Ubuntu 20.04.
sudo apt-get install -y watchman || true
fi
if ! which watchman ; then
# If installing the package didn't work, then install from source.
builddir=$(mktemp -d -t watchman.XXXXX)
git clone https://github.com/facebook/watchman.git "$builddir"
(
# Adapted from https://medium.com/@saurabh.friday/install-watchman-on-ubuntu-18-04-ba23c56eb23a
cd "$builddir"
sudo apt-get install -y autoconf automake build-essential libtool libssl-dev
git checkout tags/v4.9.0
./autogen.sh
# --enable-lenient is required for newer versions of GCC, which is
# stricter with certain constructs.
./configure --enable-lenient
make
sudo make install
)
# cleanup temporary build directory
sudo rm -rf "$builddir"
fi
}
install_postgresql() {
# Instructions taken from
# https://pgdash.io/blog/postgres-11-getting-started.html
# and
# https://wiki.postgresql.org/wiki/Apt
# Postgres 11 is not available in 18.04, so we need to add the pg apt repository.
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null
sudo add-apt-repository -y "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -c -s`-pgdg main"
sudo apt-get update
sudo apt-get install -y postgresql-14
# Set up authentication to allow connections from the postgres user with no
# password. This matches the authentication setup that homebrew installs on
# a mac. Unlike a mac, we do not need to create a postgres user manually.
sudo cp -av postgresql/pg_hba.conf "/etc/postgresql/14/main/pg_hba.conf"
sudo chown postgres.postgres "/etc/postgresql/14/main/pg_hba.conf"
sudo service postgresql restart
}
install_fastly() {
builddir=$(mktemp -d -t fastly.XXXXX)
(
cd "$builddir"
# There's no need to update the version regularly, fastly self updates
curl -LO https://github.com/fastly/cli/releases/download/v3.3.0/fastly_3.3.0_linux_amd64.deb
sudo apt install ./fastly_3.3.0_linux_amd64.deb
)
# cleanup temporary build directory
sudo rm -rf "$builddir"
}
setup_clock() {
# This shouldn't be necessary, but it seems it is.
if ! grep -q 3.ubuntu.pool.ntp.org /etc/ntp.conf; then
sudo service ntp stop
sudo ntpdate 0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org \
2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org
sudo service ntp start
fi
}
config_inotify() {
# webpack gets sad on webapp if it can only watch 8192 files (which is the
# ubuntu default).
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
}
echo
echo "Running Khan Installation Script 1.1"
echo
# We grep -i to have a good chance of catching flavors like Xubuntu.
if ! lsb_release -is 2>/dev/null | grep -iq ubuntu ; then
echo "This script is mostly tested on Ubuntu;"
echo "other distributions may or may not work."
fi
if ! echo "$SHELL" | grep -q '/bash$' ; then
echo
echo "It looks like you're using a shell other than bash!"
echo "Other shells are not officially supported. Most things"
echo "should work, but dev-support help is not guaranteed."
fi
# Run sudo once at the beginning to get the necessary permissions.
echo "This setup script needs your password to install things as root."
sudo sh -c 'echo Thanks'
install_packages
install_protoc
install_watchman
setup_clock
config_inotify
install_postgresql
install_fastly
# TODO (boris): Setup pyenv (see mac_setup:install_python_tools)
# https://opencafe.readthedocs.io/en/latest/getting_started/pyenv/
"$DEVTOOLS_DIR"/khan-dotfiles/bin/edit-system-config.sh
trap - EXIT