Skip to content

Commit 2840ed6

Browse files
authored
Add Rocky Linux support, isolate Python environment using venv, etc. (notthebee#160)
1 parent ef8168c commit 2840ed6

File tree

21 files changed

+288
-182
lines changed

21 files changed

+288
-182
lines changed

.envrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export PATH=$HOME/ansible-easy-vpn/.venv/bin:$PATH
2+
export VIRTUAL_ENV=$HOME/ansible-easy-vpn/.venv

.github/workflows/ci.yml

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,40 @@ on:
77
workflow_dispatch:
88
inputs:
99
only_ubuntu_22:
10-
description: "Only run on Ubuntu 22.04 and wait for manual input"
10+
description: "Only run on Ubuntu 22.04"
1111
required: false
1212
type: boolean
1313
default: false
1414

1515
only_ubuntu_20:
16-
description: "Only run on Ubuntu 20.04 and wait for manual input"
16+
description: "Only run on Ubuntu 20.04"
1717
required: false
1818
type: boolean
1919
default: false
2020

2121
only_debian_11:
22-
description: "Only run on Debian 11 and wait for manual input"
22+
description: "Only run on Debian 11"
2323
required: false
2424
type: boolean
2525
default: false
2626

27+
only_rocky_8:
28+
description: "Only run on Rocky 8"
29+
required: false
30+
type: boolean
31+
default: false
32+
33+
only_rocky_9:
34+
description: "Only run on Rocky 9"
35+
required: false
36+
type: boolean
37+
default: false
38+
39+
manual_mode:
40+
description: "Don't destroy the server after the setup is complete"
41+
required: false
42+
type: boolean
43+
default: false
2744
jobs:
2845
lint:
2946
runs-on: ubuntu-latest
@@ -60,11 +77,17 @@ jobs:
6077
# Only deploy on Ubuntu 22.04, don't use Letsencrypt Staging
6178
matrix=$(jq 'map(. | select((.os=="ubuntu-22.04")) )' .github/workflows/matrix_includes.json)
6279
elif [[ ${ONLY_UBUNTU_20} == 'true' ]]; then
63-
# Only deploy on Ubuntu 22.04, don't use Letsencrypt Staging
80+
# Only deploy on Ubuntu 20.04, don't use Letsencrypt Staging
6481
matrix=$(jq 'map(. | select((.os=="ubuntu-20.04")) )' .github/workflows/matrix_includes.json)
6582
elif [[ ${ONLY_DEBIAN_11} == 'true' ]]; then
66-
# Only deploy on Ubuntu 22.04, don't use Letsencrypt Staging
83+
# Only deploy on Debian 11, don't use Letsencrypt Staging
6784
matrix=$(jq 'map(. | select((.os=="debian-11")) )' .github/workflows/matrix_includes.json)
85+
elif [[ ${ONLY_ROCKY_8} == 'true' ]]; then
86+
# Only deploy on Rocky 8, don't use Letsencrypt Staging
87+
matrix=$(jq 'map(. | select((.os=="rocky-8")) )' .github/workflows/matrix_includes.json)
88+
elif [[ ${ONLY_ROCKY_9} == 'true' ]]; then
89+
# Only deploy on Rocky 9, don't use Letsencrypt Staging
90+
matrix=$(jq 'map(. | select((.os=="rocky-9")) )' .github/workflows/matrix_includes.json)
6891
else
6992
# Deploy on all supported OSes, use Letsencrypt Staging to avoid rate-limiting
7093
matrix=$(jq 'map(.)' .github/workflows/matrix_includes.json)
@@ -75,6 +98,8 @@ jobs:
7598
ONLY_UBUNTU_22: ${{ inputs.only_ubuntu_22 }}
7699
ONLY_UBUNTU_20: ${{ inputs.only_ubuntu_20 }}
77100
ONLY_DEBIAN_11: ${{ inputs.only_debian_11 }}
101+
ONLY_ROCKY_8: ${{ inputs.only_rocky_8 }}
102+
ONLY_ROCKY_9: ${{ inputs.only_rocky_9 }}
78103

79104
build:
80105
runs-on: ubuntu-latest
@@ -116,6 +141,14 @@ jobs:
116141
echo "EASYVPN_USERNAME_3=$EASYVPN_USERNAME" >> $GITHUB_OUTPUT
117142
echo "EASYVPN_PASSWORD_3=$EASYVPN_PASSWORD" >> $GITHUB_OUTPUT
118143
;;
144+
"4")
145+
echo "EASYVPN_USERNAME_4=$EASYVPN_USERNAME" >> $GITHUB_OUTPUT
146+
echo "EASYVPN_PASSWORD_4=$EASYVPN_PASSWORD" >> $GITHUB_OUTPUT
147+
;;
148+
"5")
149+
echo "EASYVPN_USERNAME_5=$EASYVPN_USERNAME" >> $GITHUB_OUTPUT
150+
echo "EASYVPN_PASSWORD_5=$EASYVPN_PASSWORD" >> $GITHUB_OUTPUT
151+
;;
119152
*)
120153
exit 1
121154
;;
@@ -138,9 +171,23 @@ jobs:
138171

139172
- name: Update apt cache
140173
run: ssh root@$SERVER_IPV4 apt update
174+
if: |
175+
matrix.os == 'debian-11' ||
176+
matrix.os == 'ubuntu-22.04' ||
177+
matrix.os == 'ubuntu-20.04'
141178
142-
- name: Install git and expect
179+
- name: Install git and expect (Debian-based)
143180
run: ssh root@$SERVER_IPV4 apt install -y git expect wamerican
181+
if: |
182+
matrix.os == 'debian-11' ||
183+
matrix.os == 'ubuntu-22.04' ||
184+
matrix.os == 'ubuntu-20.04'
185+
186+
- name: Install git and expect (CentOS 8 and 9)
187+
run: ssh root@$SERVER_IPV4 dnf install -y git expect words
188+
if: |
189+
matrix.os == 'rocky-8' ||
190+
matrix.os == 'rocky-9'
144191
145192
- uses: infraway/[email protected]
146193
with:
@@ -215,17 +262,22 @@ jobs:
215262
env:
216263
LETSENCRYPT_STAGING: ${{ needs.matrix_prep.outputs.letsencrypt_staging }}
217264

218-
- name: Wait indefinitely before destroying the server
219-
if: ${{ inputs.only_ubuntu_20 == true || inputs.only_ubuntu_22 == true || inputs.only_debian_11 == true }}
220-
run: >-
221-
sleep infinity
265+
- name: Sleep forever
266+
run: sleep infinity
267+
if: inputs.manual_mode
268+
269+
222270
outputs:
223271
EASYVPN_USERNAME_1: "${{ steps.random_username.outputs.EASYVPN_USERNAME_1 }}"
224272
EASYVPN_USERNAME_2: "${{ steps.random_username.outputs.EASYVPN_USERNAME_2 }}"
225273
EASYVPN_USERNAME_3: "${{ steps.random_username.outputs.EASYVPN_USERNAME_3 }}"
274+
EASYVPN_USERNAME_4: "${{ steps.random_username.outputs.EASYVPN_USERNAME_4 }}"
275+
EASYVPN_USERNAME_5: "${{ steps.random_username.outputs.EASYVPN_USERNAME_5 }}"
226276
EASYVPN_PASSWORD_1: "${{ steps.random_username.outputs.EASYVPN_PASSWORD_1 }}"
227277
EASYVPN_PASSWORD_2: "${{ steps.random_username.outputs.EASYVPN_PASSWORD_2 }}"
228278
EASYVPN_PASSWORD_3: "${{ steps.random_username.outputs.EASYVPN_PASSWORD_3 }}"
279+
EASYVPN_PASSWORD_4: "${{ steps.random_username.outputs.EASYVPN_PASSWORD_4 }}"
280+
EASYVPN_PASSWORD_5: "${{ steps.random_username.outputs.EASYVPN_PASSWORD_5 }}"
229281

230282
test:
231283
runs-on: ubuntu-latest

.github/workflows/matrix_includes.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,13 @@
1010
{
1111
"os":"debian-11",
1212
"index":3
13+
},
14+
{
15+
"os":"rocky-8",
16+
"index":4
17+
},
18+
{
19+
"os":"rocky-9",
20+
"index":5
1321
}
1422
]

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
.DS_Store
22
secret.yml
33
.vscode
4+
.venv
5+
.ansible

ansible.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
ask_vault_pass = True
33
inventory = inventory.yml
44
interpreter_python = python3
5+
roles_path = .ansible/roles
6+
collections_paths = .ansible/collections
57
callback_enabled = profile_tasks
68
retry_files_enabled = False
79
host_key_checking = False

bootstrap.sh

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ elif [[ -e /etc/debian_version ]]; then
2828
elif [[ -e /etc/almalinux-release || -e /etc/rocky-release || -e /etc/centos-release ]]; then
2929
os="centos"
3030
os_version=$(grep -shoE '[0-9]+' /etc/almalinux-release /etc/rocky-release /etc/centos-release | head -1)
31-
if [[ "$os_version" -lt 7 ]]; then
32-
echo "CentOS 7 or higher is required to use this installer."
33-
echo "This version of CentOS is too old and unsupported."
31+
if [[ "$os_version" -lt 8 ]]; then
32+
echo "Rocky Linux 8 or higher is required to use this installer."
33+
echo "This version of Rocky/CentOS is too old and unsupported."
3434
exit
3535
fi
3636
fi
@@ -52,7 +52,6 @@ install_dependencies_debian() {
5252
REQUIRED_PACKAGES=(
5353
sudo
5454
software-properties-common
55-
certbot
5655
dnsutils
5756
curl
5857
git
@@ -62,11 +61,10 @@ install_dependencies_debian() {
6261
python3
6362
python3-setuptools
6463
python3-apt
64+
python3-venv
6565
python3-pip
66-
python3-passlib
67-
python3-wheel
68-
python3-bcrypt
6966
aptitude
67+
direnv
7068
)
7169

7270
REQUIRED_PACKAGES_ARM64=(
@@ -90,48 +88,72 @@ install_dependencies_debian() {
9088
}
9189

9290
install_dependencies_centos() {
91+
check_root
9392
REQUIRED_PACKAGES=(
9493
sudo
95-
certbot
9694
bind-utils
9795
curl
9896
git
9997
rsync
100-
python3
101-
python3-setuptools
102-
python3-pip
103-
python3-passlib
104-
python3-wheel
105-
python3-bcrypt
98+
https://kojipkgs.fedoraproject.org//vol/fedora_koji_archive02/packages/direnv/2.12.2/1.fc28/x86_64/direnv-2.12.2-1.fc28.x86_64.rpm
10699
)
107-
108-
if [[ "$os_version" -ge 8 ]]; then
109-
$SUDO dnf update -y
110-
$SUDO dnf install -y epel-release
111-
$SUDO dnf install -y "${REQUIRED_PACKAGES[@]}"
112-
elif [[ "$os_version" -eq 7 ]]; then
113-
$SUDO yum update -y
114-
$SUDO yum install -y epel-release
115-
$SUDO yum install -y "${REQUIRED_PACKAGES[@]}"
100+
if [[ "$os_version" -eq 9 ]]; then
101+
REQUIRED_PACKAGES+=(
102+
python3
103+
python3-setuptools
104+
python3-pip
105+
python3-firewall
106+
)
107+
else
108+
REQUIRED_PACKAGES+=(
109+
python39
110+
python39-setuptools
111+
python39-pip
112+
python3-firewall
113+
kmod-wireguard
114+
https://ftp.gwdg.de/pub/linux/elrepo/elrepo/el8/x86_64/RPMS/kmod-wireguard-1.0.20220627-4.el8_7.elrepo.x86_64.rpm
115+
)
116116
fi
117+
$SUDO dnf update -y
118+
$SUDO dnf install -y epel-release
119+
$SUDO dnf install -y "${REQUIRED_PACKAGES[@]}"
117120
}
118121

122+
# Clone the Ansible playbook
123+
if [ -d "$HOME/ansible-easy-vpn" ]; then
124+
pushd $HOME/ansible-easy-vpn
125+
git pull
126+
popd
127+
else
128+
git clone https://github.com/notthebee/ansible-easy-vpn $HOME/ansible-easy-vpn
129+
fi
119130

131+
# Install all the dependencies
120132
if [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then
121133
install_dependencies_debian
122134
elif [[ "$os" == "centos" ]]; then
123135
install_dependencies_centos
124136
fi
125137

126-
check_root "-H"
127-
$SUDO pip3 install "cryptography<=36.0.2" "pyOpenSSL<=20.0.1"
128-
$SUDO pip3 install ansible~=7.1 || $SUDO pip3 install ansible
138+
# Set up a Python venv
139+
set +e
140+
if which python3.9; then
141+
PYTHON=$(which python3.9)
142+
else
143+
PYTHON=$(which python3)
144+
fi
145+
set -e
146+
cd $HOME/ansible-easy-vpn
147+
[ -d $HOME/ansible-easy-vpn/.venv ] || $PYTHON -m venv .venv
148+
export VIRTUAL_ENV="$HOME/ansible-easy-vpn/.venv"
149+
export PATH="$HOME/ansible-easy-vpn/.venv/bin:$PATH"
150+
.venv/bin/python3 -m pip install --upgrade pip
151+
.venv/bin/python3 -m pip install -r requirements.txt
152+
129153

130-
check_root
131-
# Clone the Ansible playbook
132-
[ -d "$HOME/ansible-easy-vpn" ] || git clone https://github.com/notthebee/ansible-easy-vpn $HOME/ansible-easy-vpn
133154

134-
cd $HOME/ansible-easy-vpn && ansible-galaxy install -r requirements.yml
155+
# Install the Galaxy requirements
156+
cd $HOME/ansible-easy-vpn && ansible-galaxy install --force -r requirements.yml
135157

136158
# Check if we're running on an AWS EC2 instance
137159
set +e
@@ -247,9 +269,9 @@ done
247269
echo
248270
echo "Running certbot in dry-run mode to test the validity of the domain..."
249271
if [[ "$adguard_enable" =~ ^[yY]$ ]]; then
250-
$SUDO certbot certonly --non-interactive --break-my-certs --force-renewal --agree-tos --email [email protected] --standalone --staging -d $root_host -d wg.$root_host -d auth.$root_host -d adguard.$root_host || exit
272+
$SUDO certbot certonly --non-interactive --break-my-certs --force-renewal --agree-tos --email [email protected] --standalone --staging -d $root_host -d wg.$root_host -d auth.$root_host -d adguard.$root_host || $SUDO certbot certonly --non-interactive --force-renewal --agree-tos --email [email protected] --standalone -d $root_host -d wg.$root_host -d auth.$root_host -d adguard.$root_host || exit
251273
else
252-
$SUDO certbot certonly --non-interactive --break-my-certs --force-renewal --agree-tos --email [email protected] --standalone --staging -d $root_host -d wg.$root_host -d auth.$root_host || exit
274+
$SUDO certbot certonly --non-interactive --break-my-certs --force-renewal --agree-tos --email [email protected] --standalone --staging -d $root_host -d wg.$root_host -d auth.$root_host || $SUDO certbot certonly --non-interactive --force-renewal --agree-tos --email [email protected] --standalone -d $root_host -d wg.$root_host -d auth.$root_host || exit
253275
fi
254276
echo "OK"
255277

inventory.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ all:
5050
# Language and time settings
5151
# Check here for the list of possible locales
5252
# https://docs.oracle.com/cd/E23824_01/html/E26033/glset.html
53-
locale: en_US.UTF-8
53+
locale: en_GB.UTF-8
5454

5555
timezone: Europe/Berlin
5656

@@ -88,10 +88,8 @@ all:
8888

8989
msmtp_alias_default: "{{ email }}"
9090

91-
# By default, only access via the SSH port and 51820/udp is allowed
92-
# The rest of the ports are closed
93-
enable_ufw: true
94-
ufw_ports:
91+
enable_firewall: true
92+
firewall_ports:
9593
- port: "{{ wireguard_port }}"
9694
proto: "udp"
9795
- port: "80"
@@ -103,3 +101,9 @@ all:
103101

104102
# Fail2Ban only comes with the SSH jail by default
105103
enable_fail2ban: true
104+
105+
pip_install_packages:
106+
- name: docker
107+
108+
docker_users:
109+
- "{{ username }}"

requirements.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cryptography<=36.0.2
2+
pyOpenSSL<=20.0.1
3+
certbot
4+
requests
5+
passlib
6+
bcrypt
7+
wheel
8+
ansible>=4.10

requirements.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
roles:
33
- name: chriswayg.msmtp-mailer
44
src: https://github.com/chriswayg/ansible-msmtp-mailer
5-
version: v0.6.1
5+
- name: geerlingguy.docker
6+
src: https://github.com/geerlingguy/ansible-role-docker
7+
- name: geerlingguy.pip
8+
src: https://github.com/geerlingguy/ansible-role-pip
9+
610

711
collections:
812
- name: https://github.com/ansible-collections/community.docker

0 commit comments

Comments
 (0)