Skip to content

Commit 80aef3e

Browse files
Start container testing workflow in GitHub Actions
1 parent 6829594 commit 80aef3e

File tree

7 files changed

+264
-76
lines changed

7 files changed

+264
-76
lines changed

.github/workflows/ci.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Container Environment CI
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
branches: [main, master]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Docker Buildx
16+
uses: docker/setup-buildx-action@v3
17+
18+
- name: Set up Docker Compose
19+
uses: ndeloof/install-compose-action@v0.0.1
20+
with:
21+
version: v2.23.3 # Latest stable v2 version
22+
23+
- name: Create required directories
24+
run: |
25+
mkdir -p models output .k8sgpt
26+
27+
- name: Download model file
28+
run: |
29+
curl -L "https://huggingface.co/hugging-quants/Llama-3.2-1B-Instruct-Q4_K_M-GGUF/resolve/main/llama-3.2-1b-instruct-q4_k_m.gguf" -o "models/llama-3.2-1b-instruct-q4_k_m.gguf"
30+
31+
- name: Build and start services
32+
run: |
33+
docker compose -f docker-compose.yml -f docker-compose.test.yml build
34+
docker compose -f docker-compose.yml -f docker-compose.test.yml up -d
35+
36+
- name: Wait for services to be healthy
37+
run: |
38+
chmod +x scripts/health_check.zsh
39+
./scripts/health_check.zsh || {
40+
echo "::error::Health check failed - dumping container logs"
41+
docker compose -f docker-compose.yml -f docker-compose.test.yml logs
42+
exit 1
43+
}
44+
45+
- name: Check service logs
46+
if: always()
47+
run: docker compose -f docker-compose.yml -f docker-compose.test.yml logs
48+
49+
- name: Clean up
50+
if: always()
51+
run: docker compose -f docker-compose.yml -f docker-compose.test.yml down

.github/workflows/container-ci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# TODO: These steps are temporarily disabled until LocalAI and k8sgpt services are fully implemented
2+
3+
# - name: Create required directories
4+
# run: |
5+
# mkdir -p models
6+
# mkdir -p output
7+
# mkdir -p .k8sgpt
8+
9+
# - name: Download model file
10+
# run: |
11+
# wget -O models/ggml-gpt4all-j.bin https://gpt4all.io/models/ggml-gpt4all-j.bin
12+

Dockerfile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Stage 1: Builder
2-
FROM rust:1.75-slim-bookworm as builder
2+
FROM rust:1.84-slim-bookworm as builder
33

44
# Install build dependencies
55
RUN apt-get update && apt-get install -y \
@@ -29,9 +29,12 @@ RUN apt-get update && apt-get install -y \
2929
ca-certificates \
3030
libssl3 \
3131
&& rm -rf /var/lib/apt/lists/* \
32-
&& groupadd -r appuser && useradd -r -g appuser appuser
32+
&& groupadd -r appuser && useradd -r -g appuser appuser \
33+
&& mkdir -p /home/appuser/.kube \
34+
&& chown -R appuser:appuser /home/appuser \
35+
&& chmod 700 /home/appuser/.kube
3336

34-
# Copy the binary from builder
37+
# Copy the binary from builder
3538
COPY --from=builder /usr/src/app/target/release/kube_app /usr/local/bin/
3639

3740
# Set proper permissions

docker-compose.test.yml

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
1-
version: '3.8'
2-
31
services:
4-
localai:
5-
extends:
6-
file: docker-compose.yml
7-
service: localai
8-
environment:
9-
- LOCALAI_DEBUG=true
10-
- TEST_MODE=true
11-
healthcheck:
12-
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
13-
interval: 10s
14-
timeout: 5s
15-
retries: 3
16-
start_period: 20s
2+
# Temporarily commenting out LocalAI service for faster testing
3+
# localai:
4+
# extends:
5+
# file: docker-compose.yml
6+
# service: localai
7+
# environment:
8+
# - LOCALAI_DEBUG=true
9+
# - TEST_MODE=true
10+
# healthcheck:
11+
# test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
12+
# interval: 10s
13+
# timeout: 5s
14+
# retries: 3
15+
# start_period: 20s
1716

18-
k8sgpt:
19-
extends:
20-
file: docker-compose.yml
21-
service: k8sgpt
22-
environment:
23-
- K8SGPT_TEST_MODE=true
24-
- K8SGPT_LOG_LEVEL=debug
25-
healthcheck:
26-
test: ["CMD", "k8sgpt version"]
27-
interval: 10s
28-
timeout: 5s
29-
retries: 3
17+
# Temporarily disabled for CI - will be implemented later
18+
# k8sgpt:
19+
# extends:
20+
# file: docker-compose.yml
21+
# service: k8sgpt
22+
# environment:
23+
# - K8SGPT_TEST_MODE=true
24+
# - K8SGPT_LOG_LEVEL=debug
25+
# healthcheck:
26+
# test: ["CMD", "k8sgpt version"]
27+
# interval: 10s
28+
# timeout: 5s
29+
# retries: 3
3030

3131
kube-app:
3232
extends:
@@ -37,10 +37,12 @@ services:
3737
- TEST_ENV=true
3838
- MOCK_K8S_API=true
3939
depends_on:
40-
localai:
41-
condition: service_healthy
42-
k8sgpt:
43-
condition: service_healthy
40+
# Temporarily removed LocalAI dependency for testing
41+
# localai:
42+
# condition: service_healthy
43+
# Temporarily disabled for CI - will be implemented later
44+
# k8sgpt:
45+
# condition: service_healthy
4446
healthcheck:
4547
test: ["CMD", "/app/health_check"]
4648
interval: 10s

docker-compose.yml

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,60 @@
1-
version: '3.8'
2-
31
services:
4-
localai:
5-
image: localai/localai:latest
6-
volumes:
7-
- ./models:/build/models
8-
- ./output:/build/output
9-
environment:
10-
- LOCALAI_MODELS_PATH=/build/models
11-
- LOCALAI_MODEL=llama-3.2-1b-instruct
12-
ports:
13-
- "8080:8080"
14-
healthcheck:
15-
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
16-
interval: 30s
17-
timeout: 10s
18-
retries: 3
2+
# Temporarily disabled for CI - will be implemented later
3+
# localai:
4+
# image: localai/localai:latest
5+
# volumes:
6+
# - ./models:/build/models
7+
# - ./output:/build/output
8+
# environment:
9+
# - LOCALAI_MODELS_PATH=/build/models
10+
# - LOCALAI_MODEL=ggml-gpt4all-j
11+
# ports:
12+
# - "8082:8080"
13+
# healthcheck:
14+
# test: ["CMD", "curl", "-f", "http://localhost:8080/v1/models"]
15+
# interval: 30s
16+
# timeout: 10s
17+
# retries: 3
1918

20-
k8sgpt:
21-
image: ghcr.io/k8sgpt-ai/k8sgpt:v0.3.41
22-
depends_on:
23-
localai:
24-
condition: service_healthy
25-
environment:
26-
- K8SGPT_BACKEND=localai
27-
- K8SGPT_BACKEND_URL=http://localai:8080
28-
- K8SGPT_MODEL=llama-3.2-1b-instruct
29-
- K8SGPT_CACHE=true
30-
volumes:
31-
- ./.k8sgpt:/root/.k8sgpt
32-
healthcheck:
33-
test: ["CMD", "k8sgpt", "version"]
34-
interval: 30s
35-
timeout: 10s
36-
retries: 3
19+
# Temporarily disabled for CI - will be implemented later
20+
# k8sgpt:
21+
# image: ghcr.io/k8sgpt-ai/k8sgpt:v0.3.41
22+
# command: ["serve", "--port", "8083"]
23+
# depends_on:
24+
# localai:
25+
# condition: service_healthy
26+
# ports:
27+
# - "8083:8083"
28+
# volumes:
29+
# - k8sgpt_output:/output
30+
# - /home/appuser/.kube/config:/home/appuser/.kube/config
31+
# - /home/matt/.k8sgpt:/root/.k8sgpt
32+
# environment:
33+
# - K8SGPT_BACKEND=localai
34+
# - K8SGPT_BACKEND_URL=http://localai:8080
35+
# - K8SGPT_MODEL=ggml-gpt4all-j
36+
# - K8SGPT_CACHE=true
37+
# healthcheck:
38+
# test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8083/health"]
39+
# interval: 30s
40+
# timeout: 10s
41+
# retries: 3
3742

3843
kube-app:
3944
build:
4045
context: .
4146
dockerfile: Dockerfile
42-
depends_on:
43-
localai:
44-
condition: service_healthy
45-
k8sgpt:
46-
condition: service_healthy
47+
depends_on: {}
48+
# Temporarily disabled for CI - will be implemented later
49+
# localai:
50+
# condition: service_healthy
51+
# k8sgpt:
52+
# condition: service_healthy
4753
volumes:
48-
- ${KUBECONFIG:-~/.kube/config}:/root/.kube/config:ro
54+
- ${KUBECONFIG:-~/.kube/config}:/home/appuser/.kube/config:ro
4955

5056
volumes:
5157
models:
5258
output:
53-
59+
# Temporarily disabled for CI - will be implemented later
60+
# k8sgpt_output:

scripts/health_check.zsh

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/env zsh
2+
3+
# Enable error handling
4+
setopt ERR_EXIT PIPE_FAIL NO_UNSET WARN_CREATE_GLOBAL
5+
6+
# Define colors for output
7+
typeset -A colors
8+
colors=(
9+
'reset' $'\033[0m'
10+
'red' $'\033[31m'
11+
'green' $'\033[32m'
12+
'yellow' $'\033[33m'
13+
'blue' $'\033[34m'
14+
)
15+
16+
# Constants
17+
typeset -r MAX_RETRIES=3
18+
typeset -r TIMEOUT=10
19+
typeset -r RETRY_DELAY=5
20+
21+
# Helper functions
22+
function print_status() {
23+
local message=$1
24+
local status=$2
25+
if [[ $status -eq 0 ]]; then
26+
print "${colors[green]}${message}${colors[reset]}"
27+
else
28+
print "${colors[red]}${message}${colors[reset]}"
29+
return 1
30+
fi
31+
}
32+
33+
function check_command() {
34+
local cmd=$1
35+
which $cmd &>/dev/null || {
36+
print "${colors[red]}Error: $cmd not found${colors[reset]}"
37+
return 1
38+
}
39+
}
40+
41+
function check_localai() {
42+
local retries=0
43+
while (( retries < MAX_RETRIES )); do
44+
if curl -s --max-time $TIMEOUT "http://localhost:8080/health" | grep -q "ok"; then
45+
print_status "LocalAI service is healthy" 0
46+
return 0
47+
fi
48+
((retries++))
49+
print "${colors[yellow]}Retrying LocalAI health check ($retries/$MAX_RETRIES)${colors[reset]}"
50+
sleep $RETRY_DELAY
51+
done
52+
print_status "LocalAI service is not responding" 1
53+
return 1
54+
}
55+
56+
function check_k8sgpt() {
57+
local retries=0
58+
while (( retries < MAX_RETRIES )); do
59+
if k8sgpt version &>/dev/null; then
60+
print_status "K8sGPT service is healthy" 0
61+
return 0
62+
fi
63+
((retries++))
64+
print "${colors[yellow]}Retrying K8sGPT health check ($retries/$MAX_RETRIES)${colors[reset]}"
65+
sleep $RETRY_DELAY
66+
done
67+
print_status "K8sGPT service is not responding" 1
68+
return 1
69+
}
70+
71+
function check_kube_app() {
72+
local retries=0
73+
while (( retries < MAX_RETRIES )); do
74+
if curl -s --max-time $TIMEOUT "http://localhost:3000/health" | grep -q "ok"; then
75+
print_status "Kube application is healthy" 0
76+
return 0
77+
fi
78+
((retries++))
79+
print "${colors[yellow]}Retrying Kube application health check ($retries/$MAX_RETRIES)${colors[reset]}"
80+
sleep $RETRY_DELAY
81+
done
82+
print_status "Kube application is not responding" 1
83+
return 1
84+
}
85+
86+
# Main
87+
function main() {
88+
print "${colors[blue]}Starting health checks...${colors[reset]}"
89+
90+
# Check required commands
91+
check_command "curl" || return 1
92+
check_command "k8sgpt" || return 1
93+
94+
# Initialize status
95+
local -i status=0
96+
97+
# Run health checks
98+
check_localai || status=1
99+
check_k8sgpt || status=1
100+
check_kube_app || status=1
101+
102+
if [[ $status -eq 0 ]]; then
103+
print "\n${colors[green]}All services are healthy!${colors[reset]}"
104+
return 0
105+
else
106+
print "\n${colors[red]}One or more services are unhealthy${colors[reset]}"
107+
return 1
108+
fi
109+
}
110+
111+
main "$@"
112+

src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use tokio;
55
#[tokio::main]
66
async fn main() -> Result<(), Box<dyn std::error::Error>> {
77
// Initialize Kubernetes client
8-
let client = Client::try_default().await?;
8+
let config = kube::Config::infer().await?;
9+
let client = Client::try_from(config)?;
910

1011
// Access the Namespace API
1112
let namespaces: Api<Namespace> = Api::all(client.clone());

0 commit comments

Comments
 (0)