mirror of
https://github.com/ublue-os/forge.git
synced 2025-04-17 20:13:44 +03:00
chore: Merge pull request #15 from ublue-os/tepene/host-config
feat: host configuration
This commit is contained in:
commit
12176c5718
6
.vscode/cspell_custom.txt
vendored
6
.vscode/cspell_custom.txt
vendored
|
@ -1,9 +1,15 @@
|
||||||
|
configmap
|
||||||
devcontainer
|
devcontainer
|
||||||
devcontainers
|
devcontainers
|
||||||
ENDCOLOR
|
ENDCOLOR
|
||||||
ensurepath
|
ensurepath
|
||||||
|
getent
|
||||||
gitmessage
|
gitmessage
|
||||||
|
hostvars
|
||||||
|
keygen
|
||||||
|
lineinfile
|
||||||
minica
|
minica
|
||||||
|
Mountpoint
|
||||||
pipx
|
pipx
|
||||||
rvproxy
|
rvproxy
|
||||||
ublue
|
ublue
|
||||||
|
|
10
README.md
10
README.md
|
@ -55,6 +55,12 @@ You can use the the user `ublue` and password `ublue` to login.
|
||||||
> At the moment there's only a dummy project included. Tasks for real life usage
|
> At the moment there's only a dummy project included. Tasks for real life usage
|
||||||
> will be included soon.
|
> will be included soon.
|
||||||
|
|
||||||
## Firing Up the Forge
|
## Handling the forge
|
||||||
|
|
||||||
To heat up the forge run `./setup.sh`.
|
You can use the `forge.sh` to **setup**, **heat-up** and **cool-down** the forge.
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
| ---------------------- | -------------------------------------------- |
|
||||||
|
| `./forge.sh setup` | Setup the forge for the first time or update |
|
||||||
|
| `./forge.sh heat-up` | Start the forge |
|
||||||
|
| `./forge.sh cool-down` | Stop the forge |
|
||||||
|
|
|
@ -5,11 +5,11 @@ kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
name: ublue-os_forge
|
name: ublue-os_forge
|
||||||
spec:
|
spec:
|
||||||
restartPolicy: Always
|
restartPolicy: OnFailure
|
||||||
volumes:
|
volumes:
|
||||||
- name: ublue-os_forge-minica-pvc
|
- name: ublue-os_forge-certs-pvc
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: ublue-os_forge-minica
|
claimName: ublue-os_forge-certs
|
||||||
|
|
||||||
- name: ublue-os_forge-registry-pvc
|
- name: ublue-os_forge-registry-pvc
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
|
@ -28,7 +28,7 @@ spec:
|
||||||
cpu: 200m
|
cpu: 200m
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /certs
|
- mountPath: /certs
|
||||||
name: ublue-os_forge-minica-pvc
|
name: ublue-os_forge-certs-pvc
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 443
|
- containerPort: 443
|
||||||
hostPort: 443
|
hostPort: 443
|
||||||
|
@ -42,7 +42,7 @@ spec:
|
||||||
cpu: 200m
|
cpu: 200m
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /certs
|
- mountPath: /certs
|
||||||
name: ublue-os_forge-minica-pvc
|
name: ublue-os_forge-certs-pvc
|
||||||
subPath: _.ublue.local
|
subPath: _.ublue.local
|
||||||
- mountPath: /var/lib/registry
|
- mountPath: /var/lib/registry
|
||||||
name: ublue-os_forge-registry-pvc
|
name: ublue-os_forge-registry-pvc
|
||||||
|
@ -59,12 +59,37 @@ spec:
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /var/lib/semaphore
|
- mountPath: /var/lib/semaphore
|
||||||
name: ublue-os_forge-semaphore-pvc
|
name: ublue-os_forge-semaphore-pvc
|
||||||
|
- mountPath: /certs
|
||||||
|
subPath: ssh
|
||||||
|
name: ublue-os_forge-certs-pvc
|
||||||
|
readOnly: true
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 3000
|
- containerPort: 3000
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
|
|
||||||
- name: setup.ublue.local
|
- name: setup.ublue.local
|
||||||
image: setup
|
image: setup
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /certs
|
||||||
|
name: ublue-os_forge-certs-pvc
|
||||||
|
readOnly: true
|
||||||
|
env:
|
||||||
|
- name: ANSIBLE_FORGE_HOST_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: ublue-os_forge-secure
|
||||||
|
key: ANSIBLE_FORGE_HOST_USER
|
||||||
|
|
||||||
|
- name: ANSIBLE_FORGE_HOST_BECOME_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: ublue-os_forge-secure
|
||||||
|
key: ANSIBLE_FORGE_HOST_BECOME_PASSWORD
|
||||||
|
workingDir: /ansible
|
||||||
|
command:
|
||||||
|
- ansible-playbook
|
||||||
|
args:
|
||||||
|
- main.yml
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
memory: 512Mi
|
memory: 512Mi
|
||||||
|
@ -75,4 +100,4 @@ spec:
|
||||||
image: minica
|
image: minica
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /certs
|
- mountPath: /certs
|
||||||
name: ublue-os_forge-minica-pvc
|
name: ublue-os_forge-certs-pvc
|
||||||
|
|
135
forge.sh
Executable file
135
forge.sh
Executable file
|
@ -0,0 +1,135 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
function setup {
|
||||||
|
echo -e "${YELLOW}Checking pre-requisites...${ENDCOLOR}"
|
||||||
|
check_prerequisites
|
||||||
|
echo -e "${YELLOW}Creating secret configuration...${ENDCOLOR}"
|
||||||
|
create_secrets
|
||||||
|
echo -e "${YELLOW}Heating up forge for the first time...${ENDCOLOR}"
|
||||||
|
podman play kube forge-pod.yml --build --replace & PID_BUILD=$!
|
||||||
|
wait ${PID_BUILD}
|
||||||
|
echo -e "${YELLOW}Configuring host system...${ENDCOLOR}"
|
||||||
|
configure_host & PID_CONFIG=$!
|
||||||
|
wait ${PID_CONFIG}
|
||||||
|
echo -e "${YELLOW}Configuring forge...${ENDCOLOR}"
|
||||||
|
podman logs --color -f ublue-os_forge-setup.ublue.local
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}Cleaning up secrets...${ENDCOLOR}"
|
||||||
|
delete_secrets
|
||||||
|
show_info
|
||||||
|
echo -e "${GREEN}Done. Happy forging!${ENDCOLOR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function up {
|
||||||
|
echo -e "${YELLOW}Heating up forge...${ENDCOLOR}"
|
||||||
|
podman pod start ublue-os_forge
|
||||||
|
echo -e "${GREEN}Done. Happy forging!${ENDCOLOR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function down {
|
||||||
|
echo -e "${YELLOW}Cooling down forge...${ENDCOLOR}"
|
||||||
|
podman pod stop ublue-os_forge --ignore
|
||||||
|
echo -e "${GREEN}Done. Have a nice day${ENDCOLOR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function configure_host {
|
||||||
|
if [ ! -f ~/.config/.ublue-os_forge-host-setup-done ];
|
||||||
|
then
|
||||||
|
echo "adding ssh public key to ~/.ssh/authorized_keys"
|
||||||
|
VOLUME_DIR="$(podman volume inspect ublue-os_forge-certs | jq -r '.[0].Mountpoint')"
|
||||||
|
SSH_PUBLIC_KEY_FILE="${VOLUME_DIR}/ssh/ublue-os_forge-id_ed25519.pub"
|
||||||
|
SSH_PUBLIC_KEY="$(cat ${SSH_PUBLIC_KEY_FILE})"
|
||||||
|
echo "#uBlue forge ssh key" >> ~/.ssh/authorized_keys
|
||||||
|
echo "$SSH_PUBLIC_KEY" >> ~/.ssh/authorized_keys
|
||||||
|
cp -f ${VOLUME_DIR}/tls/ublue-os_forge-root.pem ~/Downloads
|
||||||
|
touch ~/.config/.ublue-os_forge-host-setup-done
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo "Host system already configured. Nothing to do..."
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_secrets {
|
||||||
|
# Get user input
|
||||||
|
echo -e "${YELLOW}Gathering user input${ENDCOLOR}"
|
||||||
|
read -s -p "Enter sudo password for user $USER: " ANSIBLE_FORGE_HOST_BECOME_PASSWORD
|
||||||
|
cat <<EOF | jq '.|map_values(@base64)' | podman secret create ublue-os_forge-secure - >/dev/null
|
||||||
|
{
|
||||||
|
"ANSIBLE_FORGE_HOST_USER": "$USER",
|
||||||
|
"ANSIBLE_FORGE_HOST_BECOME_PASSWORD": "${ANSIBLE_FORGE_HOST_BECOME_PASSWORD}"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete_secrets {
|
||||||
|
podman secret rm ublue-os_forge-secure
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_prerequisites {
|
||||||
|
echo -e "${YELLOW}Checking sshd service${ENDCOLOR}"
|
||||||
|
SSH_SERVICE_STATUS="$(systemctl is-active sshd)"
|
||||||
|
if [ "${SSH_SERVICE_STATUS}" = "inactive" ];
|
||||||
|
then
|
||||||
|
echo -e "${RED}It looks like your sshd service is not running.${ENDCOLOR}"
|
||||||
|
echo -e "${RED}Make sure to configure and start it first.${ENDCOLOR}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}sshd service is ${SSH_SERVICE_STATUS}${ENDCOLOR}"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
echo -e "${YELLOW}Checking podman installation${ENDCOLOR}"
|
||||||
|
PODMAN_PATH=$(which podman 2>/dev/null || echo 'FALSE')
|
||||||
|
if [ "$PODMAN_PATH" == "FALSE" ];
|
||||||
|
then
|
||||||
|
echo -e "${RED}It looks like podman is not installed.${ENDCOLOR}"
|
||||||
|
echo -e "${RED}Make sure to install it first.${ENDCOLOR}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}podman is installed${SSH_SERVICE_STATUS}${ENDCOLOR}"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
echo -e "${YELLOW}Checking jq installation${ENDCOLOR}"
|
||||||
|
JQ_PATH=$(which jq 2>/dev/null || echo 'FALSE')
|
||||||
|
if [ "$JQ_PATH" == "FALSE" ];
|
||||||
|
then
|
||||||
|
echo -e "${RED}It looks like jq is not installed.${ENDCOLOR}"
|
||||||
|
echo -e "${RED}Make sure to install it first.${ENDCOLOR}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}jq is installed${SSH_SERVICE_STATUS}${ENDCOLOR}"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_info {
|
||||||
|
VOLUME_DIR="$(podman volume inspect ublue-os_forge-certs | jq -r '.[0].Mountpoint')"
|
||||||
|
echo -e "${GREEN}uBlue forge is available at: https://forge.ublue.local${ENDCOLOR}"
|
||||||
|
echo -e "${GREEN}To trust the certificate in your Browser of choice, make sure to import the root certificate from:${ENDCOLOR}"
|
||||||
|
echo -e "${GREEN}$HOME/Downloads/tls/ublue-os_forge-root.pem${ENDCOLOR}"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Bash colors
|
||||||
|
RED="\e[31m"
|
||||||
|
YELLOW="\e[33m"
|
||||||
|
GREEN="\e[32m"
|
||||||
|
ENDCOLOR="\e[0m"
|
||||||
|
|
||||||
|
# Main
|
||||||
|
case "$1" in
|
||||||
|
setup)
|
||||||
|
setup
|
||||||
|
;;
|
||||||
|
heat-up)
|
||||||
|
up
|
||||||
|
;;
|
||||||
|
cool-down)
|
||||||
|
down
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid argument: please provide 'heat-up', 'cool-down', or 'setup'"
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -1,10 +1,13 @@
|
||||||
# Source Image
|
# Source Image
|
||||||
FROM docker.io/library/golang:1.20
|
FROM docker.io/library/golang:1.20
|
||||||
|
|
||||||
|
# Copy script
|
||||||
|
WORKDIR /certs
|
||||||
|
COPY certificates.sh .
|
||||||
|
RUN chmod +x ./certificates.sh
|
||||||
|
|
||||||
# Install minica
|
# Install minica
|
||||||
RUN go install github.com/jsha/minica@latest
|
RUN go install github.com/jsha/minica@latest
|
||||||
|
|
||||||
# Generate wildcard certificate
|
# Container start command
|
||||||
WORKDIR /certs
|
CMD ["/certs/certificates.sh"]
|
||||||
RUN minica --domains "*.ublue.local,ublue.local,localhost" \
|
|
||||||
--ip-addresses 127.0.0.1
|
|
||||||
|
|
27
minica/certificates.sh
Normal file
27
minica/certificates.sh
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/sh
|
||||||
|
## Create SSH keys and certificates for uBlue-OS Forge
|
||||||
|
|
||||||
|
CERTIFICATE_DIRECTORY="/certs"
|
||||||
|
SSH_KEY_NAME="ublue-os_forge-id_ed25519"
|
||||||
|
TLS_ROOT_CERTIFICATE_NAME="ublue-os_forge-root"
|
||||||
|
|
||||||
|
if [ ! -f ${CERTIFICATE_DIRECTORY}/ssh/${SSH_KEY_NAME} ];
|
||||||
|
then
|
||||||
|
echo "uBlue Forge SSH key not present. Creating new key..."
|
||||||
|
mkdir ${CERTIFICATE_DIRECTORY}/ssh -p
|
||||||
|
# Generate SSH key
|
||||||
|
ssh-keygen -o -a 100 -t ed25519 -f ${CERTIFICATE_DIRECTORY}/ssh/${SSH_KEY_NAME} -C "forge@ublue.local"
|
||||||
|
else
|
||||||
|
echo "Existing uBlue Forge SSH key found. Nothing to do..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Creating TLS certificates
|
||||||
|
if [ ! -f ${CERTIFICATE_DIRECTORY}/tls/${TLS_ROOT_CERTIFICATE_NAME}.pem ];
|
||||||
|
then
|
||||||
|
echo "uBlue Forge TLS root not certificate present. Creating new certificates..."
|
||||||
|
mkdir ${CERTIFICATE_DIRECTORY}/tls -p
|
||||||
|
# Generate TLS certificates
|
||||||
|
minica --domains "*.ublue.local,ublue.local,localhost" --ip-addresses 127.0.0.1 -ca-cert "${CERTIFICATE_DIRECTORY}/tls/${TLS_ROOT_CERTIFICATE_NAME}.pem" -ca-key "${CERTIFICATE_DIRECTORY}/tls/${TLS_ROOT_CERTIFICATE_NAME}-key.pem"
|
||||||
|
else
|
||||||
|
echo "Existing uBlue Forge TLS root certificate found. Nothing to do..."
|
||||||
|
fi
|
|
@ -16,7 +16,7 @@
|
||||||
reverse_proxy ublue-os_forge-registry.ublue.local:5000 {
|
reverse_proxy ublue-os_forge-registry.ublue.local:5000 {
|
||||||
transport http {
|
transport http {
|
||||||
tls
|
tls
|
||||||
tls_trusted_ca_certs /certs/minica.pem
|
tls_trusted_ca_certs /certs/tls/ublue-os_forge-root.pem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
setup.sh
4
setup.sh
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Setup Universal Blue Forge
|
|
||||||
podman play kube forge-pod.yml --build --replace && podman logs --color -f ublue-os_forge-setup.ublue.local
|
|
|
@ -1,11 +1,10 @@
|
||||||
# Source Image
|
# Source Image
|
||||||
FROM docker.io/library/python:alpine3.17
|
FROM docker.io/library/python:alpine3.17
|
||||||
|
|
||||||
# Install forge setup project
|
# Install SSH
|
||||||
COPY ./ansible /ansible
|
RUN apk add openssh
|
||||||
RUN pip3 install -r /ansible/requirements.txt
|
|
||||||
RUN chmod +x /ansible/startup.sh
|
|
||||||
|
|
||||||
# Run starup script
|
# Install ansible and dependencies
|
||||||
WORKDIR /ansible
|
WORKDIR /ansible
|
||||||
CMD ["./startup.sh"]
|
COPY ./ansible .
|
||||||
|
RUN pip3 install -r ./requirements.txt
|
||||||
|
|
|
@ -7,6 +7,8 @@ roles_path = ./roles
|
||||||
collections_paths = ./collections
|
collections_paths = ./collections
|
||||||
# Localtion for plugins & modules
|
# Localtion for plugins & modules
|
||||||
library = ./library
|
library = ./library
|
||||||
|
# SSH
|
||||||
|
private_key_file = /certs/ssh/ublue-os_forge-id_ed25519
|
||||||
# Console log settings
|
# Console log settings
|
||||||
display_skipped_hosts = false
|
display_skipped_hosts = false
|
||||||
# Use the stdout_callback when running ad-hoc commands.
|
# Use the stdout_callback when running ad-hoc commands.
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
groups:
|
groups:
|
||||||
- forge
|
- forge
|
||||||
ansible_host: "{{ container_host_ip }}"
|
ansible_host: "{{ container_host_ip }}"
|
||||||
|
ansible_user: "{{ lookup('ansible.builtin.env', 'ANSIBLE_FORGE_HOST_USER') }}"
|
||||||
|
ansible_become_password: "{{ lookup('ansible.builtin.env', 'ANSIBLE_FORGE_HOST_BECOME_PASSWORD') }}"
|
||||||
|
|
||||||
- name: Add Ansible Semaphore to inventory
|
- name: Add Ansible Semaphore to inventory
|
||||||
ansible.builtin.add_host:
|
ansible.builtin.add_host:
|
||||||
|
@ -30,7 +32,31 @@
|
||||||
ansible_connection: local
|
ansible_connection: local
|
||||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||||
|
|
||||||
## TODO: Add play to configure host system
|
- name: Configure host system
|
||||||
|
hosts: forge
|
||||||
|
gather_facts: true
|
||||||
|
tasks:
|
||||||
|
- name: Add ublue.local entries to /etc/hosts
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/hosts
|
||||||
|
search_string: 127.0.0.1 registry.ublue.local forge.ublue.local
|
||||||
|
line: 127.0.0.1 registry.ublue.local forge.ublue.local
|
||||||
|
state: present
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Add ublue.local TSL root certificate to trust anchors
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /certs/tls/ublue-os_forge-root.pem
|
||||||
|
dest: /etc/pki/ca-trust/source/anchors/ublue-os_forge-root.pem
|
||||||
|
force: true
|
||||||
|
mode: "0644"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Update ca-trust store
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: update-ca-trust
|
||||||
|
changed_when: false
|
||||||
|
become: true
|
||||||
|
|
||||||
- name: Configure Ansible Semaphore
|
- name: Configure Ansible Semaphore
|
||||||
hosts: semaphore
|
hosts: semaphore
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Run setup only once
|
|
||||||
if [ ! -f /ansible/.startup-done ]; then
|
|
||||||
ansible-playbook main.yml
|
|
||||||
touch /ansible/.startup-done
|
|
||||||
fi
|
|
Loading…
Reference in a new issue