Skip to content

Commit 5f59617

Browse files
committed
proper install script
1 parent fa2f660 commit 5f59617

File tree

4 files changed

+116
-59
lines changed

4 files changed

+116
-59
lines changed

CHANGELOG.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
- Added install script
2-
3-
#### **Thread Safety** 🔒
4-
- Jobs are now also being saved to disk
5-
- `/jobs` endpoint now pulls all infos from saved JSON files
6-
- (potentially **BREAKING**) saved jobs now only use their UUID as name (`jq` can be used to filter easily)
7-
8-
#### **WSGI** 🌐
9-
- Minor import refactor
10-
- WSGI default file
11-
- changed README for gunicorn
1+
#### General 🚀
2+
- Install script now sets up a production-ready installation of ansible-link
3+
- Fetches the latest version of ansible-link from GitHub
4+
- Includes Gunicorn for handling requests
5+
- Configures Unix sockets for communication
6+
- Sets up a Python virtual environment (venv)
7+
- Updated README for install script instructions

README.md

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,33 @@
2828
Searched for a way to run our playbooks automated without the need of AWX or other big projects while still being more stable and less error-prone than custom bash scripts. So I made Ansible-Link. This projects aims to be a KISS way to run ansible jobs remotely. Essentially a RESTful API sitting on top of [ansible-runner](https://github.com/ansible/ansible-runner).
2929

3030
## Prerequisites
31-
* Python 3.7+
32-
* PIP
3331
* Your Ansible node
3432

3533
## Installation
36-
* Clone the repository (on your ansible-node):
37-
```shell
38-
git clone git@github.com:lfkdev/ansible-link.git
39-
cd ansible-link
40-
```
34+
The fastest way to set up Ansible-Link is by using the provided `install.sh` script:
4135

42-
* Install the dependencies:
43-
```shell
44-
# use virtual env
45-
pip install -r requirements.txt
46-
```
36+
1. **Download and run the install script:**
37+
```shell
38+
wget https://raw.githubusercontent.com/lfkdev/ansible-link/main/install.sh -O - | sudo bash
39+
```
40+
41+
This script will:
42+
- Check for necessary dependencies and install them if missing.
43+
- Download and install Ansible-Link.
44+
- Set up a Python virtual environment.
45+
- Configure a systemd service for Ansible-Link.
46+
47+
After the installation, you can start using Ansible-Link immediately. You probably need to change some config values for your ansible environment `/opt/ansible-link/config.yml`
4748

48-
* Set config values in `config.yml`
4949
```yaml
5050
playbook_dir: '/etc/ansible/'
5151
inventory_file: '/etc/ansible/environments/hosts'
52+
...
5253
```
5354

54-
* Start Ansible-Link
55-
```shell
56-
python3 ansible_link/ansible_link.py
57-
```
58-
The API will be accessible at localhost:port (default 5001) or wherever you bind it to.
55+
To add more workers or change the user, modify `/etc/systemd/system/ansible-link.service`
56+
> ⚠️ **Note:** Currently, only Ubuntu versions 16.04 and higher, or Debian versions 9 and higher are officially supported.
57+
> Other operating systems might also work but have not been tested. You can clone the repository and perform a manual installation if you are using a different OS.
5958
6059
## API Documentation
6160
The API documentation is available via the Swagger UI.
@@ -128,20 +127,26 @@ Leave empty to allow all playbooks. This is for the backend, you could also use
128127

129128
## Prod environment
130129

131-
**Use WSGI for prod ENV (gunicorn) + systemd service**
130+
You can use the install script `install.sh` to get a production-ready environment for Ansible-Link.
131+
132+
The install script will:
133+
- Set up a Python VENV
134+
- Configure a systemd service to manage Ansible-Link
135+
- Utilize Gunicorn as the WSGI server.
136+
137+
You can use a webserver like Caddy to add Basic Authentication and TLS to your Ansible-Link setup.
132138

133-
### unitd example file
139+
### unitD example
134140
```
135141
[Unit]
136-
Description=Ansible Link
142+
Description=Ansible Link Service
137143
After=network.target
138144

139145
[Service]
140-
User=ansible
141-
Group=ansible
142-
WorkingDirectory=/opt/ansible-link
143-
ExecStart=/usr/local/bin/gunicorn -w 1 -k gthread -b localhost:5000 wsgi:app
144-
Restart=on-failure
146+
ExecStart=$VENV_DIR/bin/gunicorn --workers 1 --bind unix:$INSTALL_DIR/ansible_link.sock -m 007 wsgi:application
147+
WorkingDirectory=$INSTALL_DIR
148+
Restart=always
149+
User=root
145150

146151
[Install]
147152
WantedBy=multi-user.target

install.sh

Lines changed: 77 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,50 @@ log() {
1212
echo "[$(date '+%Y-%m-%d %H:%M:%S')][$1] $2"
1313
}
1414

15+
display_header() {
16+
cat << "EOF"
17+
_____ _ _ _ __ _ _
18+
| _ |___ ___|_| |_| |___ ___| | |_|___| |_
19+
| | |_ -| | . | | -_|___| |__| | | '_|
20+
|__|__|_|_|___|_|___|_|___| |_____|_|_|_|_,_|
21+
EOF
22+
echo " $ANSIBLE_LINK_VERSION | github.com/lfkdev/ansible-link"
23+
echo
24+
}
25+
26+
get_latest_version() {
27+
LATEST_VERSION=$(curl -s https://api.github.com/repos/lfkdev/ansible-link/releases/latest | grep -Po '"tag_name": "\K.*?(?=")' | sed 's/^v//')
28+
if [[ -z "$LATEST_VERSION" ]]; then
29+
log "ERROR" "Failed to fetch the latest version. Using default version $ANSIBLE_LINK_VERSION."
30+
else
31+
ANSIBLE_LINK_VERSION="$LATEST_VERSION"
32+
log "INFO" "Latest version is $ANSIBLE_LINK_VERSION."
33+
fi
34+
}
35+
1536
check_root() {
1637
if [[ $EUID -ne 0 ]]; then
17-
log "ERROR" "This script must be run as root"
38+
log "ERROR" "This script must be run as root"
1839
exit 1
1940
fi
2041
}
2142

2243
check_existing_installation() {
2344
if [[ -d "$INSTALL_DIR" ]]; then
24-
read -p "ansible-link is already installed. Do you want to reinstall? (y/N) " -n 1 -r
45+
read -p "ansible-link is already installed. Do you want to reinstall? This will delete $INSTALL_DIR. (y/N) " -n 1 -r
2546
echo
26-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
47+
if [[ $REPLY =~ ^[Yy]$ ]]; then
48+
log "INFO" "Stopping ansible-link service..."
49+
if systemctl list-units --full -all | grep -Fq 'ansible-link.service'; then
50+
systemctl stop ansible-link
51+
systemctl disable ansible-link
52+
log "INFO" "ansible-link service stopped and disabled."
53+
fi
54+
log "INFO" "Removing existing installation..."
55+
if [[ -n "$INSTALL_DIR" ]]; then
56+
rm -rf "${INSTALL_DIR:?}"
57+
fi
58+
else
2759
log "INFO" "Installation cancelled."
2860
exit 0
2961
fi
@@ -39,23 +71,22 @@ check_systemd() {
3971

4072
install_dependencies() {
4173
log "INFO" "Installing dependencies..."
42-
apt-get update
43-
apt-get install -y python3 python3-venv python3-pip unzip
74+
apt-get update -qq
75+
apt-get install -y -qq python3 python3-venv python3-pip unzip
4476
}
4577

4678
download_ansible_link() {
4779
log "INFO" "Downloading ansible-link..."
4880
mkdir -p "$TEMP_DIR"
49-
wget "https://github.com/lfkdev/ansible-link/releases/download/v${ANSIBLE_LINK_VERSION}/ansible-link-${ANSIBLE_LINK_VERSION}.zip" -O "$TEMP_DIR/ansible-link.zip"
81+
wget -q "https://github.com/lfkdev/ansible-link/releases/download/v${ANSIBLE_LINK_VERSION}/ansible-link-${ANSIBLE_LINK_VERSION}.zip" -O "$TEMP_DIR/ansible-link.zip"
5082
unzip -o "$TEMP_DIR/ansible-link.zip" -d "$TEMP_DIR"
5183
}
5284

5385
install_ansible_link() {
5486
log "INFO" "Installing ansible-link..."
5587
mkdir -p "$INSTALL_DIR"
56-
mv "$TEMP_DIR/config.yml" "$TEMP_DIR/ansible_link.py" "$TEMP_DIR/webhook.py" "$TEMP_DIR/version.py" "$INSTALL_DIR/"
88+
mv "$TEMP_DIR"/*.py "$TEMP_DIR"/*.yml "$INSTALL_DIR/"
5789
}
58-
5990
setup_venv() {
6091
log "INFO" "Setting up virtual environment..."
6192
python3 -m venv "$VENV_DIR"
@@ -64,12 +95,17 @@ setup_venv() {
6495

6596
install_python_requirements() {
6697
log "INFO" "Installing Python requirements in virtual environment..."
67-
"$VENV_DIR/bin/pip" install -r "$TEMP_DIR/requirements.txt"
98+
"$VENV_DIR/bin/pip" install --upgrade pip --quiet
99+
"$VENV_DIR/bin/pip" install 'importlib-metadata<6.3,>=4.6' --quiet # importlib ubuntu 22 workaround
100+
"$VENV_DIR/bin/pip" install -r "$TEMP_DIR/requirements.txt" --quiet
101+
"$VENV_DIR/bin/pip" install gunicorn --quiet
68102
}
69103

70104
cleanup() {
71105
log "INFO" "Cleaning up..."
72-
rm -rf "$TEMP_DIR"
106+
if [[ -d "$TEMP_DIR" ]]; then
107+
rm -r "${TEMP_DIR:?}"
108+
fi
73109
}
74110

75111
detect_ansible() {
@@ -101,7 +137,7 @@ Description=Ansible Link Service
101137
After=network.target
102138
103139
[Service]
104-
ExecStart=$VENV_DIR/bin/python3 $INSTALL_DIR/ansible_link.py
140+
ExecStart=$VENV_DIR/bin/gunicorn --workers 1 --bind unix:$INSTALL_DIR/ansible_link.sock -m 007 wsgi:application
105141
WorkingDirectory=$INSTALL_DIR
106142
Restart=always
107143
User=root
@@ -115,16 +151,35 @@ EOL
115151
systemctl start ansible-link.service
116152
}
117153

118-
main() {
119-
log "INFO" "Preparing to install ansible-link version $ANSIBLE_LINK_VERSION..."
120-
121-
download_ansible_link
154+
check_os_version() {
155+
if [[ -f /etc/os-release ]]; then
156+
. /etc/os-release
157+
if [[ "$ID" == "ubuntu" && "$VERSION_ID" < "16.04" ]]; then
158+
log "ERROR" "Ubuntu version must be at least 16.04. Detected version: $VERSION_ID"
159+
exit 1
160+
elif [[ "$ID" == "debian" && "$VERSION_ID" < "9" ]]; then
161+
log "ERROR" "Debian version must be at least 9. Detected version: $VERSION_ID"
162+
exit 1
163+
elif [[ "$ID" != "ubuntu" && "$ID" != "debian" ]]; then
164+
log "ERROR" "Unsupported OS. Only Ubuntu and Debian are supported."
165+
exit 1
166+
fi
167+
else
168+
log "ERROR" "Cannot determine OS version. /etc/os-release not found."
169+
exit 1
170+
fi
171+
}
122172

123-
echo "This script will install (if not already) the following:"
124-
echo "- Python 3, python3-venv, pip"
125-
echo "- ansible-link in $INSTALL_DIR"
126-
echo "- A systemd service for ansible-link"
127-
173+
main() {
174+
echo
175+
check_os_version
176+
get_latest_version
177+
display_header
178+
echo "This script will ensure your system is set up with the following components:"
179+
echo "1. Python 3, python3-venv, and pip"
180+
echo -e "2. Ansible-Link installed in the directory: \e[32m$INSTALL_DIR\e[0m"
181+
echo "3. A SystemD service for Ansible-Link utilizing Gunicorn"
182+
echo
128183
read -p "Do you want to proceed with the installation? (y/N) " -n 1 -r
129184
echo
130185
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
@@ -137,6 +192,7 @@ main() {
137192
check_existing_installation
138193
check_systemd
139194
install_dependencies
195+
download_ansible_link
140196
install_ansible_link
141197
setup_venv
142198
install_python_requirements
@@ -149,7 +205,7 @@ main() {
149205
log "INFO" "The service is running and will start automatically on boot. ✔"
150206
log "INFO" "You can check the status with: systemctl status ansible-link. ✔"
151207
log "WARN" "Ansible user defaults to root. ⚠"
152-
log "INFO" "Please check the configuration and if needed change the default values in $INSTALL_DIR/config.yml. ⚠"
208+
log "INFO" "Please check the configuration and if needed change the default values in $INSTALL_DIR/config.yml. ⚠"
153209
}
154210

155211
main

src/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION = "2.1.1"
1+
VERSION = "2.1.2"
22

33
def get_version():
44
return VERSION

0 commit comments

Comments
 (0)