This commit is contained in:
dzikafoczka 2024-11-21 19:04:57 +01:00
parent 1cebacd7ac
commit 8b1c611e37
6 changed files with 345 additions and 45 deletions

32
README.md Normal file
View File

@ -0,0 +1,32 @@
## Instrukcja uruchomienia skryptu
1. Należy ustawić zmienne środowiskowe w pliku `.env`. Wymagane zmienne to:
- `API_KEY` - klucz API do Hetzner Cloud
- `SSH_PUBKEY` - klucz publiczny SSH (jeżeli chcemy stworzyć nowy klucz, należy go wygenerować i wkleić w tym miejscu)
- `MYSQL_ROOT_PASSWORD` - hasło do roota bazy danych MySQL
- `MYSQL_USER` - nazwa użytkownika bazy danych MySQL
- `MYSQL_PASSWORD` - hasło użytkownika bazy danych MySQL
- `MYSQL_DATABASE` - nazwa bazy danych MySQL
Przykładowy plik `.env`:
```
API_KEY=12345678
SSH_PUBKEY=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ...
MYSQL_ROOT_PASSWORD=gitea
MYSQL_USER=gitea
MYSQL_PASSWORD=gitea
MYSQL_DATABASE=gitea
```
2. Należy uruchomić skrypt `deploy.sh`. Jest to nakładka na skrypt pythonowy, zatem wymagane do jego uruchomienia jest środowisko Pythonowe.
```
./deploy.sh
```
3. Skrypt wyświetli informacje o utworzeniu zasobów w Hetzner Cloud, a także adresu serwera oraz portu, pod którymi dostępna jest aplikacja Gitea. Przykład:
```
Adres serwera Gitea: 37.27.210.205:3000
```
4. W celu usunięcia zasobów w Hetzner Cloud, należy uruchomić skrypt `delete_resources.sh`. Jest to nakładka na skrypt pythonowy, zatem wymagane do jego uruchomienia jest środowisko Pythonowe. Jeżeli podamy flage `--delete-volumes`, skrypt usunie także wolumeny.
```
./delete_resources.sh
```

5
delete_resources.sh Normal file
View File

@ -0,0 +1,5 @@
#!/bin/bash
chmod +x delete_resources_script.py
pip install -r requirements.txt
python delete_resources_script.py

View File

@ -0,0 +1,50 @@
from hcloud import Client
from dotenv import load_dotenv
import os
import sys
load_dotenv()
API_KEY = os.getenv("API_KEY")
PREFIX = "s464863"
client = Client(
token=API_KEY
)
delete_volumes = False
sys.argv = sys.argv[1:]
if len(sys.argv) > 0:
if sys.argv[0] == "--delete-volumes":
delete_volumes = True
def delete_all_servers():
servers = client.servers.get_all()
for server in servers:
if server.name.startswith(PREFIX):
action = server.volumes[0].detach()
action.wait_until_finished()
action = client.servers.delete(server)
print(
f"Usuwanie serwera {server.data_model.name} ({server.data_model.public_net.ipv4.ip}): {action.data_model.status}")
def delete_all_volumes():
volumes = client.volumes.get_all()
for volume in volumes:
if volume.name.startswith(PREFIX):
action = client.volumes.detach(volume)
action.wait_until_finished()
client.volumes.delete(volume)
print(f"Usuwanie woluminu {volume.name}")
def delete_all_networks():
networks = client.networks.get_all()
for network in networks:
if network.name.startswith(PREFIX):
action = client.networks.delete(network)
print(f"Usuwanie sieci {network.data_model.name}")
delete_all_servers()
if delete_volumes:
delete_all_volumes()
delete_all_networks()

5
deploy.sh Normal file
View File

@ -0,0 +1,5 @@
#!/bin/bash
chmod +x deploy_script.py
pip install -r requirements.txt
python deploy_script.py $1

182
deploy_script.py Normal file
View File

@ -0,0 +1,182 @@
import os
from dotenv import load_dotenv
load_dotenv()
from hcloud import Client
from hcloud.images.domain import Image
from hcloud.server_types.domain import ServerType
from hcloud.networks.domain import NetworkSubnet
from hcloud.locations.domain import Location
# Hetzner Cloud
SERVER_TYPE = "cx22"
IMAGE_UBUNTU = "ubuntu-24.04"
API_KEY = os.getenv("API_KEY")
SSH_PUBKEY = os.getenv("SSH_PUBKEY")
PREFIX = "s464863"
SSH_KEY_NAME = PREFIX
IP_RANGE = "10.10.10.0/24"
LOCATION = "hel1"
NETWORK_NAME = f"{PREFIX}-network"
DB_SERVER_NAME = f"{PREFIX}-db"
VOLUME_NAME = f"{PREFIX}-volume"
GITEA_SERVER_NAME = f"{PREFIX}-gitea"
# Credentials
MYSQL_ROOT_PASSWORD = os.getenv("MYSQL_ROOT_PASSWORD")
MYSQL_DATABASE = os.getenv("MYSQL_DATABASE")
MYSQL_USER = os.getenv("MYSQL_USER")
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD")
client = Client(
token=API_KEY
)
ssh_key = client.ssh_keys.get_by_name("broke")
if not ssh_key:
ssh_key = client.ssh_keys.create(name=SSH_KEY_NAME, public_key=SSH_PUBKEY)
print(f"Klucz {ssh_key.data_model.name} został utworzony")
else:
print(f"Pomyślnie wczytano klucz: {ssh_key.data_model.name}")
network = client.networks.get_by_name(NETWORK_NAME)
if not network:
network = client.networks.create(
name=NETWORK_NAME,
ip_range=IP_RANGE,
subnets=[
NetworkSubnet(ip_range=IP_RANGE, network_zone="eu-central", type="cloud")
]
)
print(f"Sieć {network.data_model.name} została utworzona")
else:
print(f"Znaleziono sieć o zadanej nazwie: {network.data_model.name}")
volume = client.volumes.get_by_name(VOLUME_NAME)
if not volume:
volume = client.volumes.create(
size=10,
name=VOLUME_NAME,
location=Location(LOCATION),
format="ext4"
)
print(f"Wolumen {VOLUME_NAME} został utworzony")
else:
print(f"Znaleziono wolumen o zadanej nazwie: {volume.data_model.name}")
# Pobranie ID wolumenu - potrzebne do mapowania wolumenu w docker-compose.yml
volume = client.volumes.get_by_name(VOLUME_NAME)
VOLUME_ID = volume.data_model.id
VOLUME_PATH = f"/mnt/HC_Volume_{VOLUME_ID}"
print(f"ID wolumenu: {VOLUME_ID}")
cloud_init_db = f'''#cloud-config
packages:
- apt-transport-https
- ca-certificates
- curl
- gnupg-agent
- software-properties-common
write_files:
- path: /root/docker-compose.yml
content: |
version: '3.9'
services:
db:
image: mysql:5.7
restart: always
ports:
- "10.10.10.2:3306:3306"
environment:
MYSQL_ROOT_PASSWORD: {MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: {MYSQL_DATABASE}
MYSQL_USER: {MYSQL_USER}
MYSQL_PASSWORD: {MYSQL_PASSWORD}
volumes:
- db_data:/var/lib/mysql
volumes:
db_data: {{}}
runcmd:
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
- add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- apt-get update -y
- apt-get install -y docker-ce docker-ce-cli containerd.io
- curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- chmod +x /usr/local/bin/docker-compose
- systemctl start docker
- systemctl enable docker
- cd /root/ && docker-compose up -d
'''
db_server = client.servers.create(
name=DB_SERVER_NAME,
server_type=ServerType(SERVER_TYPE),
image=Image(name=IMAGE_UBUNTU),
ssh_keys=[ssh_key],
networks=[network],
location=Location(LOCATION),
user_data=cloud_init_db
)
db_server.action.wait_until_finished()
print(f"Serwer {DB_SERVER_NAME} został utworzony")
cloud_init_gitea = f'''#cloud-config
packages:
- apt-transport-https
- ca-certificates
- curl
- gnupg-agent
- software-properties-common
write_files:
- path: /root/docker-compose.yml
content: |
version: '3.9'
services:
gitea:
image: gitea/gitea:1.22.3
volumes:
- {VOLUME_PATH}:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
restart: always
environment:
GITEA__database__DB_TYPE: mysql
GITEA__database__HOST: "10.10.10.2:3306"
GITEA__database__NAME: {MYSQL_DATABASE}
GITEA__database__USER: {MYSQL_USER}
GITEA__database__PASSWD: {MYSQL_PASSWORD}
runcmd:
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
- add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- apt-get update -y
- apt-get install -y docker-ce docker-ce-cli containerd.io
- curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- chmod +x /usr/local/bin/docker-compose
- systemctl start docker
- systemctl enable docker
- cd /root/ && docker-compose up -d
'''
gitea_server = client.servers.create(
name=f"{GITEA_SERVER_NAME}",
server_type=ServerType(SERVER_TYPE),
image=Image(name=IMAGE_UBUNTU),
ssh_keys=[ssh_key],
networks=[network],
volumes=[volume],
location=Location(LOCATION),
user_data=cloud_init_gitea
)
gitea_server.action.wait_until_finished()
print(f"Serwer {GITEA_SERVER_NAME} został utworzony")
print(f"Adres serwera Gitea: {gitea_server.server.data_model.public_net.ipv4.ip}:3000")

View File

@ -10,8 +10,8 @@
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2024-11-20T19:11:45.272667Z",
"start_time": "2024-11-20T19:11:45.259880Z"
"end_time": "2024-11-21T16:58:01.734742Z",
"start_time": "2024-11-21T16:58:01.556991Z"
}
},
"cell_type": "code",
@ -29,7 +29,7 @@
],
"id": "initial_id",
"outputs": [],
"execution_count": 14
"execution_count": 1
},
{
"metadata": {},
@ -40,8 +40,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:13:12.009718Z",
"start_time": "2024-11-20T19:13:11.998730Z"
"end_time": "2024-11-21T16:58:01.765421Z",
"start_time": "2024-11-21T16:58:01.751242Z"
}
},
"cell_type": "code",
@ -68,7 +68,7 @@
],
"id": "7c6135c6a124c6fd",
"outputs": [],
"execution_count": 15
"execution_count": 2
},
{
"metadata": {},
@ -79,8 +79,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:06:18.348087Z",
"start_time": "2024-11-20T19:06:18.336329Z"
"end_time": "2024-11-21T16:58:10.096674Z",
"start_time": "2024-11-21T16:58:10.087560Z"
}
},
"cell_type": "code",
@ -102,8 +102,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:06:20.062802Z",
"start_time": "2024-11-20T19:06:20.053862Z"
"end_time": "2024-11-21T16:58:10.985045Z",
"start_time": "2024-11-21T16:58:10.975665Z"
}
},
"cell_type": "code",
@ -129,13 +129,13 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:06:22.040059Z",
"start_time": "2024-11-20T19:06:21.799665Z"
"end_time": "2024-11-21T16:58:13.237162Z",
"start_time": "2024-11-21T16:58:12.914359Z"
}
},
"cell_type": "code",
"source": [
"ssh_key = client.ssh_keys.get_by_name(SSH_KEY_NAME)\n",
"ssh_key = client.ssh_keys.get_by_name(\"broke\")\n",
"if not ssh_key:\n",
" ssh_key = client.ssh_keys.create(name=SSH_KEY_NAME, public_key=SSH_PUBKEY)\n",
" print(f\"Klucz {ssh_key.data_model.name} został utworzony\")\n",
@ -148,7 +148,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Pomyślnie wczytano klucz: s464863\n"
"Pomyślnie wczytano klucz: broke\n"
]
}
],
@ -163,8 +163,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:06:28.021506Z",
"start_time": "2024-11-20T19:06:27.554242Z"
"end_time": "2024-11-21T16:58:14.500143Z",
"start_time": "2024-11-21T16:58:14.281194Z"
}
},
"cell_type": "code",
@ -203,8 +203,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:06:30.335643Z",
"start_time": "2024-11-20T19:06:30.130661Z"
"end_time": "2024-11-21T17:32:03.361909Z",
"start_time": "2024-11-21T17:32:03.082110Z"
}
},
"cell_type": "code",
@ -215,9 +215,11 @@
" size=10,\n",
" name=VOLUME_NAME,\n",
" location=Location(LOCATION),\n",
" automount=False\n",
" format=\"ext4\"\n",
" )\n",
"print(f\"Wolumen {VOLUME_NAME} został utworzony\")"
" print(f\"Wolumen {VOLUME_NAME} został utworzony\")\n",
"else:\n",
" print(f\"Znaleziono wolumen o zadanej nazwie: {volume.data_model.name}\")"
],
"id": "1ab418d3246a60ea",
"outputs": [
@ -225,17 +227,17 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Wolumen s464863-volume został utworzony\n"
"Znaleziono wolumen o zadanej nazwie: s464863-volume\n"
]
}
],
"execution_count": 7
"execution_count": 19
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:07:08.651108Z",
"start_time": "2024-11-20T19:07:08.544500Z"
"end_time": "2024-11-21T17:32:05.686771Z",
"start_time": "2024-11-21T17:32:04.662473Z"
}
},
"cell_type": "code",
@ -243,7 +245,7 @@
"# Pobranie ID wolumenu - potrzebne do mapowania wolumenu w docker-compose.yml\n",
"volume = client.volumes.get_by_name(VOLUME_NAME)\n",
"VOLUME_ID = volume.data_model.id\n",
"VOLUME_PATH = f\"/mnt/HC_VOLUME_{VOLUME_ID}\"\n",
"VOLUME_PATH = f\"/mnt/HC_Volume_{VOLUME_ID}\"\n",
"print(f\"ID wolumenu: {VOLUME_ID}\")"
],
"id": "47e671674c8fc432",
@ -252,11 +254,11 @@
"name": "stdout",
"output_type": "stream",
"text": [
"ID wolumenu: 101646483\n"
"ID wolumenu: 101655125\n"
]
}
],
"execution_count": 9
"execution_count": 20
},
{
"metadata": {},
@ -267,8 +269,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:07:20.661390Z",
"start_time": "2024-11-20T19:07:20.649960Z"
"end_time": "2024-11-21T17:12:54.873272Z",
"start_time": "2024-11-21T17:12:54.861518Z"
}
},
"cell_type": "code",
@ -315,13 +317,13 @@
],
"id": "60f3510e656643a1",
"outputs": [],
"execution_count": 10
"execution_count": 14
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:07:27.235546Z",
"start_time": "2024-11-20T19:07:21.367480Z"
"end_time": "2024-11-21T17:13:00.753631Z",
"start_time": "2024-11-21T17:12:55.591434Z"
}
},
"cell_type": "code",
@ -349,7 +351,7 @@
]
}
],
"execution_count": 11
"execution_count": 15
},
{
"metadata": {},
@ -360,8 +362,8 @@
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:10:07.110489Z",
"start_time": "2024-11-20T19:10:07.097888Z"
"end_time": "2024-11-21T17:32:12.611234Z",
"start_time": "2024-11-21T17:32:12.601080Z"
}
},
"cell_type": "code",
@ -410,19 +412,19 @@
],
"id": "212f2d6a64597bdc",
"outputs": [],
"execution_count": 12
"execution_count": 21
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T19:10:15.067640Z",
"start_time": "2024-11-20T19:10:08.560697Z"
"end_time": "2024-11-21T17:32:24.838419Z",
"start_time": "2024-11-21T17:32:18.056718Z"
}
},
"cell_type": "code",
"source": [
"gitea_server = client.servers.create(\n",
" name=GITEA_SERVER_NAME,\n",
" name=f\"{GITEA_SERVER_NAME}\",\n",
" server_type=ServerType(SERVER_TYPE),\n",
" image=Image(name=IMAGE_UBUNTU),\n",
" ssh_keys=[ssh_key],\n",
@ -445,13 +447,37 @@
]
}
],
"execution_count": 13
"execution_count": 22
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T17:27:30.341628Z",
"start_time": "2024-11-20T17:27:29.295978Z"
"end_time": "2024-11-21T17:54:09.122949Z",
"start_time": "2024-11-21T17:54:09.112897Z"
}
},
"cell_type": "code",
"source": "gitea_server.server.data_model.public_net.ipv4.ip",
"id": "768b3d22dd3b3232",
"outputs": [
{
"data": {
"text/plain": [
"'37.27.83.246'"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 23
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-20T20:01:24.112181Z",
"start_time": "2024-11-20T20:01:22.339871Z"
}
},
"cell_type": "code",
@ -462,12 +488,12 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Usuwanie serwera s464863-db (95.216.200.81): running\n",
"Usuwanie serwera s464863-gitea (65.21.149.208): running\n"
"Usuwanie serwera s464863-db (65.21.149.208): running\n",
"Usuwanie serwera s464863-gitea (95.216.200.81): running\n"
]
}
],
"execution_count": 134
"execution_count": 39
},
{
"metadata": {},