Compare commits
3 Commits
81af16cedf
...
fcbd2c5452
| Author | SHA1 | Date | |
|---|---|---|---|
| fcbd2c5452 | |||
| 039531ce7b | |||
| 91fe69a0a2 |
@@ -1,19 +1,19 @@
|
|||||||
name: Zabbix APK Builder
|
name: Zabbix APK Builder
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Trigger on pushes to main/test branch
|
# Trigger on pushes to main/test branch into the zabbix-apk-builder directory
|
||||||
push:
|
push:
|
||||||
branches: [ main, test ]
|
branches: [ main, test ]
|
||||||
paths: [ 'zabbix-apk-builder/**' ]
|
paths: [ 'zabbix-apk-builder/**' ]
|
||||||
|
|
||||||
# Scheduled check for new versions (daily at 6 AM UTC)
|
# Scheduled runs at 06:00 UTC daily
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 6 * * *'
|
- cron: '0 6 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-version:
|
check-version:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# Skip the execution if the commit message contains [ci skip]
|
# Skip the execution if the commit author is the bot itself to prevent loops
|
||||||
if: ${{ gitea.event.head_commit.author.name != 'Gitea Action' }}
|
if: ${{ gitea.event.head_commit.author.name != 'Gitea Action' }}
|
||||||
outputs:
|
outputs:
|
||||||
should_build: ${{ steps.version-check.outputs.should_build }}
|
should_build: ${{ steps.version-check.outputs.should_build }}
|
||||||
@@ -30,47 +30,28 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Install jq for JSON parsing (remove sudo for container environment)
|
# Remove jq installation
|
||||||
apt-get update && apt-get install -y jq
|
# apt-get update && apt-get install -y jq
|
||||||
|
|
||||||
# Detect trigger type
|
# Detect trigger type
|
||||||
if [[ "${{ gitea.event_name }}" == "push" ]]; then
|
IS_PUSH="${{ gitea.event_name == 'push' }}"
|
||||||
echo "is_push_trigger=true" >> "${GITHUB_OUTPUT}"
|
echo "is_push_trigger=${IS_PUSH}" >> "${GITHUB_OUTPUT}"
|
||||||
echo "Triggered by push event - force build"
|
|
||||||
else
|
|
||||||
echo "is_push_trigger=false" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "Triggered by schedule - check version"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get current version from APKBUILD
|
# Get versions
|
||||||
CURRENT_VERSION=$(grep '^pkgver=' zabbix-apk-builder/APKBUILD | cut -d'=' -f2)
|
CURRENT_VERSION=$(grep '^pkgver=' zabbix-apk-builder/APKBUILD | cut -d'=' -f2)
|
||||||
echo "current_version=${CURRENT_VERSION}" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "Current version: ${CURRENT_VERSION}"
|
|
||||||
|
|
||||||
# Get latest version from Zabbix API (stable releases only)
|
|
||||||
LATEST_VERSION=$(curl -s "https://git.zabbix.com/rest/api/1.0/projects/ZBX/repos/zabbix/tags?limit=100" | \
|
LATEST_VERSION=$(curl -s "https://git.zabbix.com/rest/api/1.0/projects/ZBX/repos/zabbix/tags?limit=100" | \
|
||||||
jq -r '.values[].displayId' | \
|
grep -o '"displayId":"[^"]*"' | cut -d'"' -f4 | \
|
||||||
grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | \
|
grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | grep -v 'rc\|beta\|alpha' | \
|
||||||
grep -v 'rc\|beta\|alpha' | \
|
sort -V | tail -1)
|
||||||
sort -V | \
|
|
||||||
tail -1)
|
|
||||||
|
|
||||||
|
echo "current_version=${CURRENT_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||||
echo "latest_version=${LATEST_VERSION}" >> "${GITHUB_OUTPUT}"
|
echo "latest_version=${LATEST_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||||
echo "Latest version: ${LATEST_VERSION}"
|
|
||||||
|
|
||||||
# Determine if we should build based on trigger type
|
# Always build on push, build on schedule if versions differ
|
||||||
if [[ "${{ gitea.event_name }}" == "push" ]]; then
|
if [[ "${IS_PUSH}" == "true" || "${CURRENT_VERSION}" != "${LATEST_VERSION}" ]]; then
|
||||||
# Push trigger: always build to test changes
|
|
||||||
echo "should_build=true" >> "${GITHUB_OUTPUT}"
|
echo "should_build=true" >> "${GITHUB_OUTPUT}"
|
||||||
echo "Build required: Push trigger detected"
|
|
||||||
elif [[ "${CURRENT_VERSION}" != "${LATEST_VERSION}" ]]; then
|
|
||||||
# Schedule trigger: only build if version changed
|
|
||||||
echo "should_build=true" >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "Build required: New version ${LATEST_VERSION} available"
|
|
||||||
else
|
else
|
||||||
# Schedule trigger: no new version
|
|
||||||
echo "should_build=false" >> "${GITHUB_OUTPUT}"
|
echo "should_build=false" >> "${GITHUB_OUTPUT}"
|
||||||
echo "No build required: Version ${CURRENT_VERSION} is current"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
update-version:
|
update-version:
|
||||||
@@ -125,18 +106,6 @@ jobs:
|
|||||||
token: ${{ secrets.ACCESS_TOKEN }}
|
token: ${{ secrets.ACCESS_TOKEN }}
|
||||||
ref: ${{ gitea.ref }}
|
ref: ${{ gitea.ref }}
|
||||||
|
|
||||||
- name: Pull latest changes if version was updated
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Pull any version updates that may have been committed
|
|
||||||
if [[ "${{ needs.check-version.outputs.is_push_trigger }}" == "false" ]]; then
|
|
||||||
echo "Scheduled build - pulling latest changes"
|
|
||||||
git pull origin "${GITEA_REF_NAME:-main}" || true
|
|
||||||
else
|
|
||||||
echo "Push build - using current ref"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Verify build environment
|
- name: Verify build environment
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
@@ -151,6 +120,8 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Build Zabbix packages
|
- name: Build Zabbix packages
|
||||||
|
env:
|
||||||
|
CI_RUN_ID: ${{ gitea.run_id }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -162,42 +133,19 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "=== Verifying package build ==="
|
|
||||||
cd zabbix-apk-builder
|
cd zabbix-apk-builder
|
||||||
|
|
||||||
if [[ ! -d "packages" ]]; then
|
# Verify packages exist somewhere
|
||||||
echo "❌ ERROR: packages directory does not exist"
|
PACKAGE_COUNT=$(find packages -name "*.apk" | wc -l)
|
||||||
echo "Current directory contents:"
|
|
||||||
ls -la .
|
if [[ $PACKAGE_COUNT -eq 0 ]]; then
|
||||||
|
echo "ERROR: No packages found"
|
||||||
|
find packages -type f 2>/dev/null || echo "packages directory is empty"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for packages in the standard Alpine directory structure
|
echo "Found $PACKAGE_COUNT packages:"
|
||||||
PACKAGE_DIRS=(
|
find packages -name "*.apk" -exec ls -lh {} \;
|
||||||
"packages/*.apk"
|
|
||||||
"packages/builder/x86_64/*.apk"
|
|
||||||
"packages/x86_64/*.apk"
|
|
||||||
)
|
|
||||||
|
|
||||||
FOUND_PACKAGES=false
|
|
||||||
for pattern in "${PACKAGE_DIRS[@]}"; do
|
|
||||||
if ls $pattern >/dev/null 2>&1; then
|
|
||||||
FOUND_PACKAGES=true
|
|
||||||
echo "✅ Packages found in: $(dirname $pattern)"
|
|
||||||
ls -la $pattern
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ "$FOUND_PACKAGES" == "false" ]]; then
|
|
||||||
echo "❌ ERROR: No packages found in any expected location"
|
|
||||||
echo "Directory structure:"
|
|
||||||
find packages -type f -name "*.apk" 2>/dev/null || echo "No .apk files found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "=== Package details ==="
|
|
||||||
find packages -name "*.apk" -exec bash -c 'echo "Package: $(basename "$1")"; echo "Size: $(du -h "$1" | cut -f1)"; echo "---"' _ {} \;
|
|
||||||
|
|
||||||
- name: Upload packages as artifacts
|
- name: Upload packages as artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@@ -223,60 +171,33 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "=== Testing package installation ==="
|
# Find packages
|
||||||
|
AGENT_PKG=$(find packages -name "zabbix-agent-*.apk" | head -1)
|
||||||
|
PROXY_PKG=$(find packages -name "zabbix-proxy-*.apk" | head -1)
|
||||||
|
|
||||||
# Debug: Show what was actually downloaded
|
# Test function
|
||||||
echo "Downloaded packages:"
|
test_package() {
|
||||||
ls -la packages/
|
local pkg="$1"
|
||||||
echo "Builder directory:"
|
local binary="$2"
|
||||||
ls -la packages/builder/ 2>/dev/null || echo "No builder directory"
|
|
||||||
echo "x86_64 directory:"
|
|
||||||
ls -la packages/builder/x86_64/ 2>/dev/null || echo "No x86_64 directory"
|
|
||||||
echo "All .apk files:"
|
|
||||||
find packages/ -name "*.apk" -type f 2>/dev/null || echo "No .apk files found"
|
|
||||||
|
|
||||||
# Use known paths - packages are uploaded from zabbix-apk-builder/packages/**/*.apk
|
if [[ -f "$pkg" ]]; then
|
||||||
# and downloaded to packages/, so they should be in packages/builder/x86_64/
|
echo "Testing $(basename "$pkg")..."
|
||||||
PACKAGE_DIR="packages/builder/x86_64"
|
CONTAINER_ID=$(docker run -d alpine:latest sleep 30)
|
||||||
AGENT_PKG="$PACKAGE_DIR/zabbix-agent-7.4.2-r0.apk"
|
docker cp "$pkg" "$CONTAINER_ID:/$(basename "$pkg")"
|
||||||
PROXY_PKG="$PACKAGE_DIR/zabbix-proxy-7.4.2-r0.apk"
|
if docker exec "$CONTAINER_ID" sh -c "
|
||||||
|
apk add --allow-untrusted /$(basename "$pkg") >/dev/null 2>&1
|
||||||
|
which $binary >/dev/null 2>&1
|
||||||
|
$binary --version >/dev/null 2>&1
|
||||||
|
"; then
|
||||||
|
echo "SUCCESS: $(basename "$pkg") test passed"
|
||||||
|
else
|
||||||
|
echo "FAIL: $(basename "$pkg") test failed"
|
||||||
|
fi
|
||||||
|
docker rm -f "$CONTAINER_ID" >/dev/null
|
||||||
|
else
|
||||||
|
echo "ERROR: Package not found: $pkg"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Test agent package
|
test_package "$AGENT_PKG" "zabbix_agentd"
|
||||||
if [[ -f "$AGENT_PKG" ]]; then
|
test_package "$PROXY_PKG" "zabbix_proxy"
|
||||||
echo "Testing agent package at: $AGENT_PKG"
|
|
||||||
echo "File size: $(du -h "$AGENT_PKG")"
|
|
||||||
|
|
||||||
# Create container, copy package, install and test
|
|
||||||
CONTAINER_ID=$(docker run -d alpine:latest sleep 30)
|
|
||||||
docker cp "$AGENT_PKG" "$CONTAINER_ID:/$(basename "$AGENT_PKG")"
|
|
||||||
docker exec "$CONTAINER_ID" sh -c "
|
|
||||||
ls -la /$(basename "$AGENT_PKG")
|
|
||||||
apk add --allow-untrusted /$(basename "$AGENT_PKG")
|
|
||||||
which zabbix_agentd
|
|
||||||
zabbix_agentd --version
|
|
||||||
" && echo "✅ Agent test passed" || echo "❌ Agent test failed"
|
|
||||||
docker rm -f "$CONTAINER_ID" >/dev/null
|
|
||||||
else
|
|
||||||
echo "⚠️ Agent package not found at $AGENT_PKG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test proxy package
|
|
||||||
if [[ -f "$PROXY_PKG" ]]; then
|
|
||||||
echo "Testing proxy package at: $PROXY_PKG"
|
|
||||||
echo "File size: $(du -h "$PROXY_PKG")"
|
|
||||||
|
|
||||||
# Create container, copy package, install and test
|
|
||||||
CONTAINER_ID=$(docker run -d alpine:latest sleep 30)
|
|
||||||
docker cp "$PROXY_PKG" "$CONTAINER_ID:/$(basename "$PROXY_PKG")"
|
|
||||||
docker exec "$CONTAINER_ID" sh -c "
|
|
||||||
ls -la /$(basename "$PROXY_PKG")
|
|
||||||
apk add --allow-untrusted /$(basename "$PROXY_PKG")
|
|
||||||
which zabbix_proxy
|
|
||||||
zabbix_proxy --version
|
|
||||||
" && echo "✅ Proxy test passed" || echo "❌ Proxy test failed"
|
|
||||||
docker rm -f "$CONTAINER_ID" >/dev/null
|
|
||||||
else
|
|
||||||
echo "⚠️ Proxy package not found at $PROXY_PKG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Package deployment test completed"
|
|
||||||
@@ -4,8 +4,7 @@ Automated Alpine Linux package builder for Zabbix Agent and Proxy with CI/CD pip
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- 🔄 **Automatic Version Detection**: Monitors Zabbix releases using official Bitbucket API
|
- 🔄 **Automatic Version Detection**: Monitors Zabbix releases using Bitbucket API
|
||||||
- 🏗️ **Docker-based Building**: Consistent, reproducible builds in isolated environment
|
|
||||||
- 🚀 **CI/CD Pipeline**: Full automation from version detection to package deployment
|
- 🚀 **CI/CD Pipeline**: Full automation from version detection to package deployment
|
||||||
- 📦 **Multi-package Support**: Builds agent and proxy packages
|
- 📦 **Multi-package Support**: Builds agent and proxy packages
|
||||||
- 🧪 **Automated Testing**: Tests package installation in Alpine containers
|
- 🧪 **Automated Testing**: Tests package installation in Alpine containers
|
||||||
@@ -13,34 +12,24 @@ Automated Alpine Linux package builder for Zabbix Agent and Proxy with CI/CD pip
|
|||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### 1. Repository Setup
|
### Prerequisites
|
||||||
|
|
||||||
|
- Docker installed
|
||||||
|
- Gitea repository with Actions enabled
|
||||||
|
|
||||||
|
### Manual Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone this repository
|
# Clone the repository
|
||||||
git clone https://git.mbuz.uk/mbuz/Zabbix.git
|
git clone <your-gitea-repo>
|
||||||
cd zabbix-apk-builder
|
cd zabbix-apk-builder
|
||||||
|
|
||||||
# Make build script executable
|
|
||||||
chmod +x build.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Manual Build
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build packages locally
|
# Build packages locally
|
||||||
|
chmod +x build.sh
|
||||||
./build.sh
|
./build.sh
|
||||||
|
|
||||||
# Packages will be in ./packages/
|
# Check built packages
|
||||||
ls -la packages/
|
ls -la packages/builder/x86_64/
|
||||||
```
|
|
||||||
|
|
||||||
### 3. CI/CD Setup
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run the setup script
|
|
||||||
./setup-cicd.sh
|
|
||||||
|
|
||||||
# Follow the prompts to configure GitHub secrets
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Package Information
|
## Package Information
|
||||||
@@ -51,19 +40,12 @@ ls -la packages/
|
|||||||
2. **zabbix-proxy** - Zabbix Proxy
|
2. **zabbix-proxy** - Zabbix Proxy
|
||||||
3. **zabbix** - Meta package
|
3. **zabbix** - Meta package
|
||||||
|
|
||||||
### Current Version
|
|
||||||
|
|
||||||
- **Zabbix Version**: 7.4.2
|
|
||||||
- **Alpine Base**: latest
|
|
||||||
- **Architecture**: all
|
|
||||||
|
|
||||||
## CI/CD Pipeline
|
## CI/CD Pipeline
|
||||||
|
|
||||||
### Automatic Triggers
|
### Automatic Triggers
|
||||||
|
|
||||||
- **Daily**: Checks for new Zabbix versions at 6 AM UTC
|
- **Daily**: Checks for new Zabbix versions at 6 AM UTC
|
||||||
- **Push**: Builds when code changes in main/test branches
|
- **Push**: Builds when code changes in main/test branches
|
||||||
- **Manual**: Force builds via Gitea Actions
|
|
||||||
|
|
||||||
### Version Detection
|
### Version Detection
|
||||||
|
|
||||||
@@ -91,48 +73,22 @@ GITEA_SSH_KEY # SSH private key for Gitea access
|
|||||||
### File Structure
|
### File Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
.
|
zabbix-git/
|
||||||
└── zabbix-git
|
└── zabbix-apk-builder/
|
||||||
└── zabbix-apk-builder
|
├── .gitea/
|
||||||
├── .gitea/workflows # Workflows for Gitea actions
|
│ └── workflows/
|
||||||
├── .gitignore # Ignore files
|
│ └── build.yaml # Main CI/CD pipeline
|
||||||
├── APKBUILD # APKBUILD file for Zabbix
|
├── APKBUILD # Alpine package definition
|
||||||
├── Dockerfile # Dockerfile for building packages
|
├── Dockerfile # Build environment container
|
||||||
├── README.md # Project description
|
├── README.md # This file
|
||||||
├── build.sh # Script for manual builds
|
├── build.sh # Local build script
|
||||||
├── packages/ # Directory for built packages
|
├── packages/ # Generated packages (gitignored)
|
||||||
├── zabbix-agent.* # Agent configuration files
|
├── zabbix-agent.confd # Agent configuration
|
||||||
└── zabbix-proxy.* # Proxy configuration files
|
├── zabbix-agent.initd # Agent init script
|
||||||
```
|
├── zabbix-agent.pre-install # Agent pre-install script
|
||||||
|
├── zabbix-proxy.confd # Proxy configuration
|
||||||
## Usage
|
├── zabbix-proxy.initd # Proxy init script
|
||||||
|
└── zabbix-proxy.pre-install # Proxy pre-install script
|
||||||
### Install Packages
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Add repository
|
|
||||||
echo "http://gitea-repo/mbuz/Zabbix/raw/branch/main/alpine/v3.18/main" >> /etc/apk/repositories
|
|
||||||
|
|
||||||
# Update and install
|
|
||||||
apk update
|
|
||||||
apk add zabbix-agent
|
|
||||||
|
|
||||||
# Enable and start
|
|
||||||
rc-update add zabbix-agent default
|
|
||||||
rc-service zabbix-agent start
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Configure agent
|
|
||||||
vim /etc/zabbix/zabbix_agentd.conf
|
|
||||||
|
|
||||||
# Set server IP
|
|
||||||
Server=your.zabbix.server
|
|
||||||
|
|
||||||
# Restart service
|
|
||||||
rc-service zabbix-agent restart
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
@@ -154,28 +110,16 @@ docker run --rm -it \
|
|||||||
|
|
||||||
### Branch Strategy
|
### Branch Strategy
|
||||||
|
|
||||||
- **main**: Production releases, auto-deployed
|
- **main**: Production releases, merge only
|
||||||
- **test**: Testing and validation, no auto-deploy
|
- **test**: Testing and validation
|
||||||
|
|
||||||
### Making Changes
|
### Making Changes
|
||||||
|
|
||||||
1. Create feature branch from `test`
|
1. Create feature branch from `main`
|
||||||
2. Test changes thoroughly
|
2. Test changes thoroughly
|
||||||
3. Merge to `test` for CI validation
|
3. Validate CI
|
||||||
4. Merge to `main` for production release
|
4. Merge to `main`
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Build Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check build logs
|
|
||||||
docker logs $(docker ps -l -q)
|
|
||||||
|
|
||||||
# Manual build debug
|
|
||||||
docker run -it --rm -v $(pwd):/build alpine:3.18 sh
|
|
||||||
cd /build && ./build.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Version Detection
|
### Version Detection
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user