Compare commits

...

2 Commits
main ... pierre

Author SHA1 Message Date
pb
d1fbd0fac4 first improvement for interactive setup 2025-04-29 18:13:15 +02:00
pb
cdd8dd8a03 first improvement for interactive setup 2025-04-29 18:11:56 +02:00
4 changed files with 239 additions and 1 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
k8s/deployed_config
k8s/deployed_config
docker/build_logs/

30
docker/README.md Normal file
View File

@ -0,0 +1,30 @@
# A guide to effective docker deployment for Open Cloud
We need a reliable process using the existing tools and the creation of new one to have a consistant deployment of Open Cloud when each service is running in a docker container.
This document aims at addressing :
- The existing tools used
- The functionning of said tools
- The needed improvement (bugs/new features)
- The required configuration for each service
## Steps
- Downloading the repos : `oc-deploy/download_oc.py` uses the interactivity offered by python's library to select and follow the cloning of the repos on the forge, `oc-deploy/clone_opencloud_microservices.sh` is more straifhtforward using bash.
- Selecting the services to launch : `build_containers.sh` asks the user for the services that need to be launched. The user can choose non essential services (in front, monitord and shared) to be added to tthe list of minimum service to run open cloud (auth, catalog, datacenter, peer, workspace, worflow, scheduler, schedulerd)
- Verify if the service really need a `docker build` : this operation is time and resource consumming, so we need to check :
- is a container already runs
- does an image already exist
and prompt the user if he wants to proceed with the build, or just start a container with the existing image or let the the current container run.
- Fill the configuration file for each service selected to be built.
## Todo
- Implement a script that interacts with the user to fill the configuration json file
- Remove the filed json file from the forge to prevent that data from other dev are stored and used during build, which would lead the services to be missconfigured
- We could let some generic value, like ports, container addresses...

129
docker/build_containers.sh Executable file
View File

@ -0,0 +1,129 @@
#!/bin/bash
# List of services to build
MINIMUM_REPOS=(
"oc-auth"
"oc-catalog"
"oc-datacenter"
"oc-peer"
"oc-scheduler"
"oc-schedulerd"
"oc-workflow"
"oc-workspace"
)
EXTRA_REPOS=(
"oc-front"
"oc-shared"
"oc-monitord"
)
REPOS=("${MINIMUM_REPOS[@]}") # Start with minimum repos
OC_ROOT="$(realpath ../..)"
DOCKER_BUILD="$(pwd)"
LOG_DIR="$DOCKER_BUILD/build_logs"
mkdir -p "$LOG_DIR"
cd "$OC_ROOT" || exit 1
# Function to build a service
build_service() {
local service=$1
local logfile="$LOG_DIR/$service.log"
echo "[START] Building $service..."
docker build -t "$service" "$OC_ROOT/$service" > "$logfile" 2>&1 &
echo $! # Return PID
}
# Track running builds
declare -A pids
declare -a active_services=()
# Select services to build
echo "🔧 Optional extra services:"
for i in "${!EXTRA_REPOS[@]}"; do
echo " [$((i+1))] ${EXTRA_REPOS[$i]}"
done
read -p "🟡 Do you want to add any extra services? Enter numbers separated by space (e.g., 1 3), or press Enter to skip: " -a selected
for index in "${selected[@]}"; do
if [[ "$index" =~ ^[0-9]+$ ]] && (( index >= 1 && index <= ${#EXTRA_REPOS[@]} )); then
REPOS+=("${EXTRA_REPOS[$((index-1))]}")
else
echo "⚠️ Invalid selection: $index"
fi
done
echo "✅ Selected services:"
for repo in "${REPOS[@]}"; do
echo " - $repo"
done
# Launch builds
for service in "${REPOS[@]}"; do
IMAGE_NAME="$service"
# Check if the image exists locally
if docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then
read -p "🟡 Image '$IMAGE_NAME' already exists. Rebuild? (y/N): " rebuild
if [[ "$rebuild" =~ ^[Yy]$ ]]; then
echo "🔄 Rebuilding image for '$IMAGE_NAME'..."
else
echo "⏭️ Skipping build for '$IMAGE_NAME'."
continue
fi
fi
# Check if a container is already running from this image
if docker ps --filter "ancestor=$IMAGE_NAME" --format '{{.ID}}' | grep -q .; then
echo "✅ A container from image '$IMAGE_NAME' is already running. Skipping build."
else
SERVICE_PATH="$OC_ROOT/$service"
if [ -d "$SERVICE_PATH" ]; then
build_service "$service" &
pids["$service"]=$!
active_services+=("$service")
else
echo "⚠️ Directory not found for $service. Skipping."
fi
fi
done
echo "========================"
echo "Building: ${active_services[*]}"
echo "========================"
# Monitor logs for each build in parallel
for service in "${active_services[@]}"; do
logfile="$LOG_DIR/$service.log"
(
tail -n 0 -f "$logfile" | while IFS= read -r line; do
# Highlight docker build steps
if [[ "$line" =~ Step\ ([0-9]+/[0-9]+) ]]; then
echo -e "[$service] 🚧 ${BASH_REMATCH[0]}: $line"
else
echo "[$service] $line"
fi
done
) &
done
# Wait for all builds to complete
for pid in "${pids[@]}"; do
wait "$pid"
done
for service in "${active_services[@]}"; do
cd $OC_ROOT/service
docker compose up -d
done
echo "✅ All builds completed."

78
download_oc.py Executable file
View File

@ -0,0 +1,78 @@
#/bin/python3
import requests
from bs4 import BeautifulSoup
import inquirer
import os
import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed
from rich.console import Console
from rich.table import Table
from rich.live import Live
# URLs des pages à analyser
urls = [
'https://cloud.o-forge.io/explore/repos?page=1',
'https://cloud.o-forge.io/explore/repos?page=2'
]
def get_all_repo(urls):
repositories = []
for url in urls:
response = requests.get(url)
response.raise_for_status() # Vérifie si la requête a réussi
soup = BeautifulSoup(response.text, 'html.parser')
titles = soup.find_all(class_='flex-item-title')
for title in titles:
repo_name = title.get_text(strip=True)
if repo_name.startswith('core/'):
repositories.append(repo_name.split("core/")[1])
return repositories
def git_clone_repo(repo: str, dir: str, status: dict):
status[repo] = "⏳ Cloning..."
try:
if os.path.exists(f"{dir}/{repo}") :
subprocess.run(["git", "-C", f"{dir}/{repo}","pull"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
base_url = f"https://cloud.o-forge.io/core/{repo}.git"
subprocess.run(["git", "clone", base_url, f"{dir}/{repo}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
status[repo] = "✅ Done"
except Exception as e:
status[repo] = f"❌ Failed: {e}"
def display_status(status):
table = Table(title="Repository Cloning Status")
table.add_column("Repository", justify="left")
table.add_column("Status", justify="right")
for repo, state in status.items():
table.add_row(repo, state)
return table
repositories = get_all_repo(urls)
cwd = os.getcwd()
questions = [
inquirer.Checkbox('repo_choice',
message=f"Which Open Cloud repo do you want to download ? (Will be download in {cwd})?",
choices=repositories,
),
]
selected_repo = inquirer.prompt(questions)
status = {repo: "Waiting" for repo in selected_repo["repo_choice"]}
with ThreadPoolExecutor() as executor:
futures = {executor.submit(git_clone_repo, repo, cwd, status): repo for repo in selected_repo["repo_choice"]}
with Live(display_status(status), refresh_per_second=2) as live:
for future in as_completed(futures):
live.update(display_status(status))