Push code
This commit is contained in:
152
scripts/build-deb.sh
Executable file
152
scripts/build-deb.sh
Executable file
@@ -0,0 +1,152 @@
|
||||
#!/bin/bash
|
||||
# build-deb.sh - Build Debian package for FeatherDDNS (runs inside container)
|
||||
set -e
|
||||
|
||||
VERSION="${VERSION:-1.0.0}"
|
||||
ARCH="amd64"
|
||||
PACKAGE_NAME="featherddns"
|
||||
MAINTAINER="Steven Tracey <steven@nevets.tech>"
|
||||
HOMEPAGE="https://git.nevets.tech/Steven/FeatherDDNS"
|
||||
|
||||
BUILD_DIR="build/${PACKAGE_NAME}_${VERSION}_${ARCH}"
|
||||
|
||||
echo "Building ${PACKAGE_NAME} version ${VERSION}..."
|
||||
|
||||
# Clean and create build directory
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir -p "$BUILD_DIR/DEBIAN"
|
||||
mkdir -p "$BUILD_DIR/usr/bin"
|
||||
mkdir -p "$BUILD_DIR/etc/featherddns"
|
||||
mkdir -p "$BUILD_DIR/lib/systemd/system"
|
||||
|
||||
# Copy and strip binary
|
||||
echo "Copying binary..."
|
||||
cp "bin/FeatherDDNS" "$BUILD_DIR/usr/bin/featherddns"
|
||||
strip "$BUILD_DIR/usr/bin/featherddns"
|
||||
chmod 755 "$BUILD_DIR/usr/bin/featherddns"
|
||||
|
||||
# Copy config if exists
|
||||
if [ -f "config.json.example" ]; then
|
||||
echo "Copying configuration..."
|
||||
cp "config.json.example" "$BUILD_DIR/etc/featherddns/config.json"
|
||||
chmod 644 "$BUILD_DIR/etc/featherddns/config.json"
|
||||
fi
|
||||
|
||||
# Copy systemd service if exists
|
||||
if [ -f "featherddns.service" ]; then
|
||||
echo "Copying systemd service..."
|
||||
cp "featherddns.service" "$BUILD_DIR/lib/systemd/system/"
|
||||
chmod 644 "$BUILD_DIR/lib/systemd/system/featherddns.service"
|
||||
fi
|
||||
|
||||
# Create control file
|
||||
cat > "$BUILD_DIR/DEBIAN/control" <<EOF
|
||||
Package: ${PACKAGE_NAME}
|
||||
Version: ${VERSION}
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: ${ARCH}
|
||||
Maintainer: ${MAINTAINER}
|
||||
Depends: libc6
|
||||
Homepage: ${HOMEPAGE}
|
||||
Description: FeatherDDNS - Lightweight Dynamic DNS Server
|
||||
A lightweight dynamic DNS server for updating DNS records
|
||||
via HTTP API requests.
|
||||
EOF
|
||||
|
||||
# Create conffiles if config exists
|
||||
if [ -f "$BUILD_DIR/etc/featherddns/config.json" ]; then
|
||||
cat > "$BUILD_DIR/DEBIAN/conffiles" <<EOF
|
||||
/etc/featherddns/config.json
|
||||
EOF
|
||||
chmod 644 "$BUILD_DIR/DEBIAN/conffiles"
|
||||
fi
|
||||
|
||||
# Create postinst script
|
||||
cat > "$BUILD_DIR/DEBIAN/postinst" <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
# Create featherddns user if it doesn't exist
|
||||
if ! getent passwd featherddns > /dev/null; then
|
||||
useradd --system --home-dir /var/lib/featherddns --shell /bin/false featherddns
|
||||
fi
|
||||
|
||||
# Create directories
|
||||
mkdir -p /var/lib/featherddns
|
||||
mkdir -p /var/log/featherddns
|
||||
chown featherddns:featherddns /var/lib/featherddns
|
||||
chown featherddns:featherddns /var/log/featherddns
|
||||
|
||||
# Reload systemd
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl daemon-reload >/dev/null || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
chmod 755 "$BUILD_DIR/DEBIAN/postinst"
|
||||
|
||||
# Create prerm script
|
||||
cat > "$BUILD_DIR/DEBIAN/prerm" <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade)
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl stop featherddns.service >/dev/null 2>&1 || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
chmod 755 "$BUILD_DIR/DEBIAN/prerm"
|
||||
|
||||
# Create postrm script
|
||||
cat > "$BUILD_DIR/DEBIAN/postrm" <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
remove)
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl daemon-reload >/dev/null || true
|
||||
fi
|
||||
;;
|
||||
purge)
|
||||
rm -rf /etc/featherddns
|
||||
rm -rf /var/lib/featherddns
|
||||
rm -rf /var/log/featherddns
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl daemon-reload >/dev/null || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
chmod 755 "$BUILD_DIR/DEBIAN/postrm"
|
||||
|
||||
# Build the package
|
||||
echo "Building package..."
|
||||
dpkg-deb --build --root-owner-group "$BUILD_DIR"
|
||||
|
||||
# Move to dist directory
|
||||
mkdir -p dist
|
||||
mv "${BUILD_DIR}.deb" "dist/"
|
||||
|
||||
echo "Package built: dist/${PACKAGE_NAME}_${VERSION}_${ARCH}.deb"
|
||||
|
||||
# Run lintian check
|
||||
if command -v lintian > /dev/null 2>&1; then
|
||||
echo "Running lintian check..."
|
||||
lintian "dist/${PACKAGE_NAME}_${VERSION}_${ARCH}.deb" || true
|
||||
fi
|
||||
|
||||
echo "Done!"
|
||||
116
scripts/package.sh
Executable file
116
scripts/package.sh
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/bin/bash
|
||||
# package.sh - Build Debian package for FeatherDDNS using a Debian container
|
||||
#
|
||||
# Usage: ./scripts/package.sh [version]
|
||||
#
|
||||
# Environment Variables:
|
||||
# CONTAINER_RUNTIME Container runtime to use (default: podman)
|
||||
# VERSION Override package version
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
IMAGE_NAME="featherddns-debian-builder"
|
||||
CONTAINER_RUNTIME="${CONTAINER_RUNTIME:-podman}"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
success() { echo -e "${GREEN}[OK]${NC} $1"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
|
||||
|
||||
# Get version from Makefile or argument
|
||||
get_version() {
|
||||
grep "^VERSION" "$PROJECT_ROOT/Makefile" 2>/dev/null | head -1 | sed 's/.*:= *//' | tr -d ' '
|
||||
}
|
||||
|
||||
VERSION="${1:-${VERSION:-$(get_version)}}"
|
||||
VERSION="${VERSION:-1.0.0}"
|
||||
|
||||
info "Packaging FeatherDDNS version ${VERSION}"
|
||||
|
||||
# Check container runtime
|
||||
if ! command -v "$CONTAINER_RUNTIME" >/dev/null 2>&1; then
|
||||
error "Container runtime '$CONTAINER_RUNTIME' not found"
|
||||
info "Install podman or docker, or set CONTAINER_RUNTIME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
info "Using container runtime: $CONTAINER_RUNTIME"
|
||||
|
||||
# Check binary exists
|
||||
if [[ ! -f "$PROJECT_ROOT/bin/FeatherDDNS" ]]; then
|
||||
error "Binary not found: bin/FeatherDDNS"
|
||||
info "Build first with: make build"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
success "Binary found: bin/FeatherDDNS"
|
||||
|
||||
# Build container image if needed
|
||||
info "Checking for debian-builder image..."
|
||||
|
||||
NEED_BUILD=false
|
||||
if ! $CONTAINER_RUNTIME image exists "$IMAGE_NAME" 2>/dev/null; then
|
||||
info "Image does not exist, building..."
|
||||
NEED_BUILD=true
|
||||
else
|
||||
DOCKERFILE_TIME=$(stat -c %Y "$PROJECT_ROOT/Dockerfile.debian-builder" 2>/dev/null || echo 0)
|
||||
IMAGE_TIME=$($CONTAINER_RUNTIME image inspect "$IMAGE_NAME" --format '{{.Created}}' 2>/dev/null | xargs -I{} date -d {} +%s 2>/dev/null || echo 0)
|
||||
if [[ "$DOCKERFILE_TIME" -gt "$IMAGE_TIME" ]]; then
|
||||
info "Dockerfile is newer than image, rebuilding..."
|
||||
NEED_BUILD=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$NEED_BUILD" == "true" ]]; then
|
||||
if ! $CONTAINER_RUNTIME build -t "$IMAGE_NAME" -f "$PROJECT_ROOT/Dockerfile.debian-builder" "$PROJECT_ROOT"; then
|
||||
error "Failed to build debian-builder image"
|
||||
exit 1
|
||||
fi
|
||||
success "debian-builder image built"
|
||||
else
|
||||
success "debian-builder image is up-to-date"
|
||||
fi
|
||||
|
||||
# Create dist directory
|
||||
mkdir -p "$PROJECT_ROOT/dist"
|
||||
|
||||
# Determine SELinux mount option
|
||||
MOUNT_OPT=""
|
||||
if command -v getenforce >/dev/null 2>&1 && [[ "$(getenforce 2>/dev/null)" != "Disabled" ]]; then
|
||||
MOUNT_OPT=":Z"
|
||||
info "SELinux detected, using :Z mount flag"
|
||||
fi
|
||||
|
||||
# Run packaging in container
|
||||
info "Running packaging in container..."
|
||||
|
||||
if ! $CONTAINER_RUNTIME run --rm \
|
||||
-v "${PROJECT_ROOT}:/build${MOUNT_OPT}" \
|
||||
-e "VERSION=${VERSION}" \
|
||||
-w /build \
|
||||
"$IMAGE_NAME" \
|
||||
/bin/bash -c "./scripts/build-deb.sh"; then
|
||||
error "Container packaging failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify output
|
||||
DEB_FILE=$(find "$PROJECT_ROOT/dist" -name "featherddns_*.deb" -type f 2>/dev/null | head -1)
|
||||
|
||||
if [[ -n "$DEB_FILE" ]]; then
|
||||
success "Package created: $DEB_FILE"
|
||||
ls -lh "$DEB_FILE"
|
||||
else
|
||||
error "Package not found in dist/"
|
||||
ls -la "$PROJECT_ROOT/dist/" 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
success "Packaging complete!"
|
||||
150
scripts/publish-to-gitea.sh
Executable file
150
scripts/publish-to-gitea.sh
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
# Upload Debian packages to Gitea APT registry
|
||||
set -e
|
||||
|
||||
GITEA_URL="${GITEA_URL:-https://git.nevets.tech}"
|
||||
GITEA_OWNER="${GITEA_OWNER:-steven}"
|
||||
GITEA_TOKEN="${GITEA_TOKEN}"
|
||||
DIST_DIR="${DIST_DIR:-dist}"
|
||||
DISTRIBUTION="${DISTRIBUTION:-trixie}" # Debian 13
|
||||
COMPONENT="${COMPONENT:-main}"
|
||||
PACKAGE_FILTER="${PACKAGE_FILTER:-}" # Optional filter for specific package
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
if [ -z "$GITEA_TOKEN" ]; then
|
||||
echo -e "${RED}Error: GITEA_TOKEN environment variable not set${NC}"
|
||||
echo "Set it with: export GITEA_TOKEN='your-token-here'"
|
||||
echo ""
|
||||
echo "The token must have the following permissions:"
|
||||
echo " - write:package (to upload packages)"
|
||||
echo " - read:package (to read package metadata)"
|
||||
echo ""
|
||||
echo "Create a token at: ${GITEA_URL}/user/settings/applications"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$DIST_DIR" ]; then
|
||||
echo -e "${RED}Error: Distribution directory $DIST_DIR not found${NC}"
|
||||
echo "Build packages first with: make package"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}Publishing packages to Gitea APT registry...${NC}"
|
||||
echo "Repository: ${GITEA_URL}/api/packages/${GITEA_OWNER}/debian"
|
||||
echo "Distribution: ${DISTRIBUTION}"
|
||||
echo "Component: ${COMPONENT}"
|
||||
if [ -n "$PACKAGE_FILTER" ]; then
|
||||
echo "Filter: ${PACKAGE_FILTER}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Verify token has package access
|
||||
echo -e "${BLUE}Verifying token permissions...${NC}"
|
||||
VERIFY_CODE=$(curl -s -w "%{http_code}" -o /tmp/gitea_verify.txt \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/user")
|
||||
|
||||
if [ "$VERIFY_CODE" -eq 200 ]; then
|
||||
USER=$(grep -o '"login":"[^"]*"' /tmp/gitea_verify.txt | cut -d'"' -f4)
|
||||
echo -e "${GREEN}✓ Token authenticated as user: ${USER}${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Token verification failed (HTTP ${VERIFY_CODE})${NC}"
|
||||
cat /tmp/gitea_verify.txt
|
||||
echo ""
|
||||
echo "Please check your GITEA_TOKEN and try again."
|
||||
exit 1
|
||||
fi
|
||||
rm -f /tmp/gitea_verify.txt
|
||||
echo ""
|
||||
|
||||
SUCCESS_COUNT=0
|
||||
FAIL_COUNT=0
|
||||
|
||||
for deb in "$DIST_DIR"/*.deb; do
|
||||
if [ -f "$deb" ]; then
|
||||
PACKAGE_NAME=$(basename "$deb")
|
||||
|
||||
# Skip if filter is set and package doesn't match
|
||||
if [ -n "$PACKAGE_FILTER" ]; then
|
||||
if [[ ! "$PACKAGE_NAME" =~ ^${PACKAGE_FILTER}_ ]]; then
|
||||
echo -e "${BLUE}Skipping ${PACKAGE_NAME} (doesn't match filter)${NC}"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}Uploading ${PACKAGE_NAME}...${NC}"
|
||||
|
||||
# Try uploading with token authentication
|
||||
HTTP_CODE=$(curl -X PUT \
|
||||
-w "%{http_code}" \
|
||||
-o /tmp/gitea_upload_response.txt \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary @"${deb}" \
|
||||
"${GITEA_URL}/api/packages/${GITEA_OWNER}/debian/pool/${DISTRIBUTION}/${COMPONENT}/upload")
|
||||
|
||||
if [ "$HTTP_CODE" -eq 201 ] || [ "$HTTP_CODE" -eq 200 ]; then
|
||||
echo -e "${GREEN}✓ Uploaded ${PACKAGE_NAME}${NC}"
|
||||
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
||||
else
|
||||
echo -e "${RED}✗ Failed to upload ${PACKAGE_NAME} (HTTP ${HTTP_CODE})${NC}"
|
||||
echo "Response:"
|
||||
cat /tmp/gitea_upload_response.txt
|
||||
echo ""
|
||||
|
||||
# Provide troubleshooting guidance for common errors
|
||||
if [ "$HTTP_CODE" -eq 401 ]; then
|
||||
echo -e "${RED}Authentication failed. Please check:${NC}"
|
||||
echo " 1. Token is valid and not expired"
|
||||
echo " 2. Token has 'write:package' permission"
|
||||
echo " 3. You have access to the '${GITEA_OWNER}' organization"
|
||||
echo " Create/update token at: ${GITEA_URL}/user/settings/applications"
|
||||
elif [ "$HTTP_CODE" -eq 403 ]; then
|
||||
echo -e "${RED}Permission denied. Ensure the token has package write access.${NC}"
|
||||
elif [ "$HTTP_CODE" -eq 404 ]; then
|
||||
echo -e "${RED}Repository not found. Verify the owner '${GITEA_OWNER}' exists.${NC}"
|
||||
fi
|
||||
echo ""
|
||||
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}Upload Summary:${NC}"
|
||||
echo -e "${GREEN}Successful: ${SUCCESS_COUNT}${NC}"
|
||||
if [ "$FAIL_COUNT" -gt 0 ]; then
|
||||
echo -e "${RED}Failed: ${FAIL_COUNT}${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if [ "$SUCCESS_COUNT" -gt 0 ]; then
|
||||
echo -e "${GREEN}Repository setup instructions:${NC}"
|
||||
echo ""
|
||||
echo " # Add GPG key"
|
||||
echo " sudo curl ${GITEA_URL}/api/packages/${GITEA_OWNER}/debian/repository.key -o /etc/apt/keyrings/gitea-${GITEA_OWNER}.asc"
|
||||
echo ""
|
||||
echo " # Add repository"
|
||||
echo " echo \"deb [signed-by=/etc/apt/keyrings/gitea-${GITEA_OWNER}.asc] ${GITEA_URL}/api/packages/${GITEA_OWNER}/debian ${DISTRIBUTION} ${COMPONENT}\" | sudo tee -a /etc/apt/sources.list.d/gitea-${GITEA_OWNER}.list"
|
||||
echo ""
|
||||
echo " # Update package list"
|
||||
echo " sudo apt update"
|
||||
echo ""
|
||||
echo " # Install packages"
|
||||
echo " sudo apt install featherddns"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
rm -f /tmp/gitea_upload_response.txt
|
||||
|
||||
if [ "$FAIL_COUNT" -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user