From 63a6502452f4c6926cec63c7122ecf26e98ec464 Mon Sep 17 00:00:00 2001 From: MatOgr Date: Wed, 28 Dec 2022 21:36:57 +0100 Subject: [PATCH] Task 3.2 completion commit --- .gitignore | 1 + gitea-deploy/clean.sh | 9 + gitea-deploy/deploy.sh | 13 ++ gitea-deploy/just_do_everything.py | 283 +++++++++++++++++++++++++++++ 4 files changed, 306 insertions(+) create mode 100644 .gitignore create mode 100755 gitea-deploy/clean.sh create mode 100755 gitea-deploy/deploy.sh create mode 100755 gitea-deploy/just_do_everything.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..016309e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*/token_file \ No newline at end of file diff --git a/gitea-deploy/clean.sh b/gitea-deploy/clean.sh new file mode 100755 index 0000000..59fddaa --- /dev/null +++ b/gitea-deploy/clean.sh @@ -0,0 +1,9 @@ +#!/bin/bash +chmod +x just_do_everything.py +echo "### Creating venv is probably a good idea - let's make one..." +python3 -m venv gitea_venv +source gitea_venv/bin/activate +echo "### Now install hcloud module..." +pip install -q hcloud +echo "### And clear last deployment results..." +python just_do_everything.py --clean diff --git a/gitea-deploy/deploy.sh b/gitea-deploy/deploy.sh new file mode 100755 index 0000000..b0a39e4 --- /dev/null +++ b/gitea-deploy/deploy.sh @@ -0,0 +1,13 @@ +#!/bin/bash +chmod +x just_do_everything.py +python3 -m venv gitea_venv +source ./gitea_venv/bin/activate +pip install -q hcloud +echo "############################" +echo "Let's clean everything from last run..." +python just_do_everything.py --clean +echo "--------------------------------------------------------------------------" +echo " Success! I guess..." +echo "############################" +echo "Let's spawn some new machines!" +python just_do_everything.py --create \ No newline at end of file diff --git a/gitea-deploy/just_do_everything.py b/gitea-deploy/just_do_everything.py new file mode 100755 index 0000000..a4c5fd9 --- /dev/null +++ b/gitea-deploy/just_do_everything.py @@ -0,0 +1,283 @@ +#!/bin/pythonS +from hcloud import Client, APIException +from hcloud.images.domain import Image +from hcloud.networks.domain import NetworkSubnet +from hcloud.server_types.domain import ServerType +from hcloud.locations.domain import Location +from pathlib import Path +import sys + + +specific_name = "s478841" +key_name = f"ssh-{specific_name}" +net_name = f"gitea-net-{specific_name}" +volume_name = f"gitea-volume-{specific_name}" +db_name = f"gitea-db-{specific_name}" +server_name = f"gitea-server-{specific_name}" +location = Location("hel1") + + +# DB yaml +INIT_DB_CONTENT = r"""#cloud-config +packages: + - apt-transport-https + - ca-certificates + - curl + - gnupg-agent + - software-properties-common +write_files: + - path: /root/docker-compose.yml + content: | + version: "2" + services: + db: + image: postgres:14 + restart: always + ports: + - "10.10.10.2:5432:5432" + environment: + - POSTGRES_USER=gitea + - POSTGRES_PASSWORD=gitea + - POSTGRES_DB=gitea + volumes: + - ./postgres:/var/lib/postgresql/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 +""" + +# Gitea service yaml +INIT_GITEA = r"""#cloud-config +packages: + - apt-transport-https + - ca-certificates + - curl + - gnupg-agent + - software-properties-common +write_files: + - path: /root/docker-compose.yml + content: | + version: "2" + services: + server: + image: gitea/gitea:1.17.3-rootless + environment: + - GITEA__server__DOMAIN=${DOMAIN} + - GITEA__database__DB_TYPE=postgres + - GITEA__database__HOST="10.10.10.2:5432" + - GITEA__database__NAME=gitea + - GITEA__database__USER=gitea + - GITEA__database__PASSWD=gitea + restart: always + volumes: + - /mnt/gitea-volume-s478841/data:/var/lib/gitea + - /mnt/gitea-volume-s478841/config:/etc/gitea + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - "3000:3000" + - "2222:2222" +""" + + +def create_client(creds_path): + with open(creds_path, "r") as f: + token = str(f.readline()).strip() + client = Client(token=token) + print("The CLIENT has been CREATED") + return client + + +def load_key(key_folder, pub_key_name): + home_path = Path.home().joinpath(key_folder, pub_key_name) + print(f"\t\tUsing the {home_path} file") + with open(home_path) as f: + key = f.readline() + print("\t\tThe SSH KEY has been LOADED") + return key + + +def create_key(client, key_name, key_folder, pub_key_name): + print("The SSH KEY has been...") + key_of_power = load_key(key_folder, pub_key_name) + key = client.ssh_keys.create(name=key_name, public_key=key_of_power) + print("\tCREATED") + return key + + +def remove_key(client, key_name): + print("The KEY has been...", end="") + try: + action = client.ssh_keys.delete(client.ssh_keys.get_by_name(key_name)) + action.wait_until_finished() + except AttributeError: + pass + print("DELETED") + + +def create_network(client, net_name, ip_range): + print("The NETWORK has been...", end="") + net = client.networks.create( + name=net_name, + ip_range=ip_range, + subnets=[ + NetworkSubnet(ip_range=ip_range, network_zone="eu-central", type="cloud") + ], + ) + print("CREATED") + return net + + +def remove_network(client, net_name): + print("The NETWORK has been...", end="") + try: + action = client.networks.delete(client.networks.get_by_name(net_name)) + action.wait_until_finished() + except AttributeError: + pass + + print("DELETED") + + +def create_volume(client, volume_name, location): + print("The VOLUME has been...", end="") + volume = client.volumes.create( + name=volume_name, size=10, format="ext4", location=location + ) + print("CREATED") + return volume + + +def remove_volume(client, volume_name): + print("The VOLUME has been...", end="") + try: + volume = client.volumes.get_by_name(volume_name) + try: + action = client.volumes.detach(volume) + action.wait_until_finished() + except APIException: + pass + action = client.volumes.delete(volume) + action.wait_until_finished() + except AttributeError: + pass + print("DELETED") + + +def create_db(client, db_name, ssh_key, vnet, location, user_data): + print("The DB SERVER has been CREATED:", end=" ") + db = client.servers.create( + name=db_name, + server_type=ServerType("cpx11"), + image=Image(name="ubuntu-22.04"), + ssh_keys=[ssh_key], + networks=[vnet], + location=location, + user_data=user_data, + ) + db.action.wait_until_finished() + print(db.action.complete) + return db + + +def remove_db(client, db_name): + print("The DB SERVER has been...", end="") + try: + action = client.servers.delete(client.servers.get_by_name(db_name)) + action.wait_until_finished() + except AttributeError: + pass + print("DELETED") + + +def create_gitea_server( + client, server_name, ssh_key, vnet, volume, location, user_data +): + print("The GITEA SERVER has been CREATED:", end=" ") + gitea_server = client.servers.create( + name=server_name, + server_type=ServerType("cpx11"), + image=Image(name="ubuntu-22.04"), + ssh_keys=[ssh_key], + networks=[vnet], + volumes=[volume.volume], + automount=True, + location=location, + user_data=user_data, + ) + gitea_server.action.wait_until_finished() + print(gitea_server.action.complete) + return gitea_server + + +def remove_gitea_server(client, server_name): + print("The GITEA SERVER has been...", end="") + try: + action = client.servers.delete(client.servers.get_by_name(server_name)) + action.wait_until_finished() + except AttributeError: + pass + print("DELETED") + + +if __name__ == "__main__": + + client = create_client("./token_file") + + action = sys.argv[-1] + + if action == "--create": + ssh_key = create_key(client, key_name, ".ssh", "id_ed25519.pub") + vnet = create_network(client, net_name, "10.10.10.0/24") + volume = create_volume(client, volume_name, location) + db = create_db(client, db_name, ssh_key, vnet, location, INIT_DB_CONTENT) + + # Prepare the yaml script for creating the gitea server + RUNCMD = f"""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/ + - IP=$(hostname -I | cut -d ' ' -f 1) + - echo "DOMAIN=$IP" >> .env + - sudo mkfs.ext4 -F /dev/disk/by-id/scsi-0HC_Volume_{volume.volume.id} + - mkdir /mnt/{volume_name} + - mount -o discard,defaults /dev/disk/by-id/scsi-0HC_Volume_{volume.volume.id} /mnt/{volume_name} + - echo "/dev/disk/by-id/scsi-0HC_Volume_{volume.volume.id} /mnt/{volume_name} ext4 discard,nofail,defaults 0 0" >> /etc/fstab + - mkdir /mnt/{volume_name}/data + - mkdir /mnt/{volume_name}/config + - sudo chown 1000:1000 /mnt/{volume_name}/config/ /mnt/{volume_name}/data + - docker-compose up -d + """ + + RUN_GITEA = f"{INIT_GITEA}\n{RUNCMD}" + + # Create a gitea server using loaded credentials and created resources + server = create_gitea_server( + client, server_name, ssh_key, vnet, volume, location, RUN_GITEA + ) + print( + f"You can access the server (in a few minutes) under the address: http://{server.server.data_model.public_net.ipv4.ip}:3000" + ) + print("\n\n\t\tHave fun!") + elif action == "--clean": + remove_gitea_server(client, server_name) + remove_db(client, db_name) + remove_network(client, net_name) + remove_volume(client, volume_name) + remove_key(client, key_name) + print("\n\n\t\tIt was nice to meet you!") + else: + print(f"\nSorry, don't know what the'{action}' means...bye!")