#!/bin/sh # SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC # SPDX-FileCopyrightText: (C) 2025 Serena Willis # # SPDX-License-Identifier: AGPL-3.0 # # BuildMan 0.0.1 # Distributed CI/CD system with portability to older UNIX systems # # bm - primary BuildMan script # # Copyright (C) 2025 Coherent Logic Development LLC # # Author: Serena Willis # PROGN=`basename $0` if [ -f "/etc/default/bm" ] then . /etc/default/bm else echo "${PROGN} error: no /etc/default/bm" exit 1 fi if [ -z ${BUILDMAN_BASE} ] then echo "${PROGN} error: BUILDMAN_BASE undefined" exit 1 fi if [ -z ${BUILDMAN_UID} ] then echo "${PROGN} error: BUILDMAN_UID undefined" exit 1 fi if [ -z ${BUILDMAN_GID} ] then echo "${PROGN} error: BUILDMAN_GID undefined" exit 1 fi #if [ $EUID -ne ${BUILDMAN_UID} ] #then # echo "${PROGN} error: must be run as user \"${BUILDMAN_USER}\"" # exit 1 #fi ACTION="" PROJECT="" BUILD_HOST="" OS=`uname` PYES="no" if [ "$OS" = "SCO_SV" ] ; then THOST=`hostname -s` PATH=/usr/gnu/bin:$PATH export PATH else if [ "$OS" = "SunOS" ] ; then THOST=`hostname` else THOST=`hostname -s` fi fi tmphost=`echo ${THOST} | cut -d. -f1` THOST="${tmphost}" while getopts ':p:h:a:bl:o:y' OPTION do case $OPTION in y) PYES="yes" ;; l) ACTION="list" TOLIST="${OPTARG}" ;; o) OPTIONS="${OPTARG}" ;; p) PROJECT="${OPTARG}" ;; a) ACTION="add" TOADD="${OPTARG}" ;; b) ACTION="build" ;; h) BUILD_HOST="${OPTARG}" ;; esac done if [ "${ACTION}" = "" ] then echo "${PROGN}: no action specified" exit 1 fi if [ ! -z "${PROJECT}" ] then PROJECT_BASE="${BUILDMAN_BASE}/projects/${PROJECT}" if [ "${ACTION}" = "add" -a ! -d ${PROJECT_BASE} ] then echo "$PROGN: creating ${PROJECT} in ${PROJECT_BASE}..." mkdir -p "${PROJECT_BASE}" fi if [ ! -d "${PROJECT_BASE}" ] then echo "$PROGN error: project ${PROJECT} not defined [${PROJECT_BASE}]" exit 1 fi fi case $ACTION in list) case $TOLIST in p|projects) ls -d -1 ${BUILDMAN_BASE}/projects/* ;; h|hosts) BHOSTS=`ls -1 "${BUILDMAN_BASE}/projects/${PROJECT}/hosts"` for BHOST in ${BHOSTS} do echo ${BHOST} done ;; *) echo "$PROGN error: invalid list specifier \"${TOLIST}\"" exit 1 ;; esac ;; add) case $TOADD in p|project) if [ -z "${PROJECT}" ] then echo "$PROGN error: no project specified (use -p)" exit 1 fi PBASE="${BUILDMAN_BASE}/projects/${PROJECT}" if [ -d "${PBASE}" ] then echo "$PROGN error: project \"${PROJECT}\" already exists" exit 1 fi echo "$PROGN: creating directory structure for project \"${PROJECT}\"" mkdir -p "${PBASE}/hosts" mkdir -p "${PBASE}/scripts" ;; h|host) if [ -z "${PROJECT}" ] then echo "$PROGN error: no project specified (use -p)" exit 1 fi PBASE="${BUILDMAN_BASE}/projects/${PROJECT}" if [ ! -d "${PBASE}" ] then echo "$PROGN error: project \"${PROJECT}\" does not exist" exit 1 fi if [ -z "${BUILD_HOST}" ] then echo "$PROGN error: no host specified (use -h)" exit 1 fi HBASE="${PBASE}/hosts/${BUILD_HOST}" if [ -d "${HBASE}" ] then echo "$PROGN error: build host \"${BUILD_HOST}\" already exists" exit 1 fi if [ -z "${OPTIONS}" ] then echo "$PROGN error: must pass -o \"os:version:arch\"" exit 1 fi PLSTR="${BUILD_HOST}:${OPTIONS}:buildman::" H_PLATFORM=`echo ${PLSTR} | cut -d: -f2` H_VERSION=`echo ${PLSTR} | cut -d: -f3` H_ARCH=`echo ${PLSTR} | cut -d: -f4` if [ "${PYES}" = "no" ] then echo echo "Host Details" echo "============" echo "Project: ${PROJECT}" echo "Hostname: ${BUILD_HOST}" echo "Platform: ${H_PLATFORM}" echo "Version: ${H_VERSION}" echo "Architecture: ${H_ARCH}" echo read -n 1 -p "OK to create? (y/n) " YORN echo if [ "${YORN}" = "y" -o "${YORN}" = "Y" ] then CONF=1 else echo "$PROGN: aborted" exit 2 fi fi echo "$PROGN: adding host \"${BUILD_HOST}\" to project \"${PROJECT}\"" mkdir -p "${HBASE}" mkdir -p "${HBASE}/jobs" mkdir -p "${HBASE}/logs" PFILE="${PBASE}/${H_PLATFORM}-platform.list" echo echo "==================================================" echo " Don't forget to add the BuildMan cron job" echo " to ${BUILDMAN_USER}@${BUILD_HOST}" echo "==================================================" echo echo "${PLSTR}" >> "${PFILE}" cd ${PBASE} ls -1 *-platform.list | cut -d- -f1 | sort | uniq > platforms.list ;; esac ;; build) if [ -z "${BUILD_HOST}" ] then echo "$PROGN error: no build host specified" exit 1 fi if [ "${BUILD_HOST}" != '*' ] then BUILD_BASE="${PROJECT_BASE}/hosts/${BUILD_HOST}" if [ ! -d "${BUILD_BASE}" ] then echo "$PROGN error: build host ${BUILD_HOST} not configured" exit 1 fi BUILD_WANTED="${PROJECT_BASE}/hosts/${BUILD_HOST}/build-wanted" if [ -f "${BUILD_WANTED}" ] then echo "$PROGN error: build already requested on host ${BUILD_HOST}" exit 1 fi touch "${BUILD_WANTED}" echo "$PROGN: build of project ${PROJECT} requested on ${BUILD_HOST}" else BHOSTS=`ls -1 "${BUILDMAN_BASE}/projects/${PROJECT}/hosts"` for BUILD_HOST in ${BHOSTS} do BUILD_BASE="${PROJECT_BASE}/hosts/${BUILD_HOST}" if [ ! -d "${BUILD_BASE}" ] then echo "$PROGN error: build host ${BUILD_HOST} not configured" continue fi BUILD_WANTED="${PROJECT_BASE}/hosts/${BUILD_HOST}/build-wanted" if [ -f "${BUILD_WANTED}" ] then echo "$PROGN error: build already requested on ${BUILD_HOST}" continue fi touch "${BUILD_WANTED}" > /dev/null 2>&1 if [ $? = 0 ] then echo "$PROGN: build of project ${PROJECT} requested on build host ${BUILD_HOST}" else echo "$PROGN: error requesting build of ${PROJECT} on build host ${BUILD_HOST}" fi done fi ;; esac