-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython_install.sh
More file actions
121 lines (101 loc) · 3.38 KB
/
python_install.sh
File metadata and controls
121 lines (101 loc) · 3.38 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
#!/usr/bin/env bash
set -euo pipefail
# -----------------------------------------------------------------------------
# Logging
# -----------------------------------------------------------------------------
# LOG_DIR="/var/log/foxorepo"
# LOG_FILE="$LOG_DIR/install-$(date +%Y%m%d-%H%M%S).log"
# mkdir -p "$LOG_DIR"
# exec > >(tee -a "$LOG_FILE") 2>&1
log() { echo "[INFO ] $(date '+%F %T') $*"; }
warn() { echo "[WARN ] $(date '+%F %T') $*"; }
die() { echo "[ERROR] $(date '+%F %T') $*" >&2; exit 1; }
trap 'die "Script failed at line $LINENO"' ERR
# -----------------------------------------------------------------------------
# Configuration
# -----------------------------------------------------------------------------
RUN_DIR=$(dirname "$0")
PY_ROOT_DIR="$1" # eg. /opt/python
PY_VER="$2" # eg. 3.13.9
PY_NAME="Python-$PY_VER"
PY_TAR_NAME="$PY_NAME.tgz"
PY_DOWNLOAD_URL="https://www.python.org/ftp/python/$PY_VER/$PY_TAR_NAME"
PY_INSTALL_DIR="$PY_ROOT_DIR/$PY_NAME"
PY_TARGET="$PY_INSTALL_DIR/bin/python3"
PY_INSTALL_WORKDIR="$PY_ROOT_DIR/$PY_NAME-build"
PY_INSTALL_WORKDIR_EXTRACT="$PY_INSTALL_WORKDIR/$PY_NAME"
PY_INSTALL_TAR="$PY_INSTALL_WORKDIR/$PY_TAR_NAME"
PY_LOCAL_TAR="$RUN_DIR/$PY_TAR_NAME"
# -----------------------------------------------------------------------------
# Install build dependencies
# -----------------------------------------------------------------------------
log "Installing build dependencies via apt"
APT_PKGS=(
build-essential
make
gcc
git
curl
ca-certificates
zlib1g-dev
libssl-dev
libffi-dev
libbz2-dev
libreadline-dev
libsqlite3-dev
liblzma-dev
libncurses-dev
uuid-dev
tk-dev
)
missing_pkgs=()
for pkg in "${APT_PKGS[@]}"; do
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
missing_pkgs+=("$pkg")
fi
done
if [[ ${#missing_pkgs[@]} -gt 0 ]]; then
log "Missing apt packages: ${missing_pkgs[*]}"
sudo apt-get update -y
sudo apt-get install -y "${missing_pkgs[@]}"
else
log "All apt packages already installed - skipping"
fi
log "Build dependencies installed"
# -----------------------------------------------------------------------------
# Download Python source tarball, if needed
# -----------------------------------------------------------------------------
mkdir -p "$PY_INSTALL_WORKDIR"
if [[ -f "$PY_LOCAL_TAR" ]] && [[ ! -f "$PY_INSTALL_TAR" ]]; then
log "Copying Python tarball from $PY_LOCAL_TAR to $PY_INSTALL_TAR"
cp "$PY_LOCAL_TAR" "$PY_INSTALL_TAR"
fi
if [[ ! -f "$PY_INSTALL_TAR" ]]; then
log "Downloading Python source: $PY_DOWNLOAD_URL"
curl -fL --retry 5 --retry-delay 2 -o "$PY_INSTALL_TAR" "$PY_DOWNLOAD_URL"
else
log "Python tarball exists: $PY_INSTALL_TAR"
fi
# -----------------------------------------------------------------------------
# Build and install Python (does NOT replace system python)
# -----------------------------------------------------------------------------
if [[ ! -x "$PY_TARGET" ]]; then
cd $PY_INSTALL_WORKDIR
log "Extracting $PY_TAR_NAME"
rm -rf "$PY_INSTALL_WORKDIR_EXTRACT"
tar -xzf "$PY_INSTALL_TAR"
cd "$PY_INSTALL_WORKDIR_EXTRACT"
log "Configuring Python build"
./configure \
--prefix="$PY_INSTALL_DIR" \
--enable-optimizations \
--with-ensurepip=install
log "Compiling Python"
make -j"$(nproc)"
log "Installing Python into $PY_INSTALL_DIR"
sudo make install
else
warn "Python already installed at $PY_INSTALL_DIR - skipping build"
fi
cd "$PY_INSTALL_DIR"
log "Python version: $("$PY_TARGET" --version)"