util.zsh
1 #- 2 # Copyright (c) 2023-2025 The HardenedBSD Project 3 # 4 # Redistribution and use in source and binary forms, with or without 5 # modification, are permitted provided that the following conditions 6 # are met: 7 # 1. Redistributions of source code must retain the above copyright 8 # notice, this list of conditions and the following disclaimer. 9 # 2. Redistributions in binary form must reproduce the above copyright 10 # notice, this list of conditions and the following disclaimer in the 11 # documentation and/or other materials provided with the distribution. 12 # 13 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 # SUCH DAMAGE. 24 # 25 # Author: Shawn Webb <shawn.webb@hardenedbsd.org> 26 27 function check_sanity() { 28 if [ -z "${LOCKFILE}" ]; then 29 echo "[-] LOCKFILE required" >&2 30 return 1 31 fi 32 33 if [ -f "${LOCKFILE}" ]; then 34 echo "[-] Build locked. Remove ${LOCKFILE}." >&2 35 return 1 36 fi 37 38 if [ $(id -u) -gt 0 ]; then 39 echo "[-] Must be run as root" >&2 40 return 1 41 fi 42 43 if [ -z "${SRCDIR}" ]; then 44 echo "[-] SRCDIR required" >&2 45 return 1 46 fi 47 48 if [ ! -d ${SRCDIR} ]; then 49 echo "[] ${SRCDIR} not a directory" >&2 50 return 1 51 fi 52 53 if [ -z "${BRANCH}" ]; then 54 echo "[-] BRANCH required" >&2 55 return 1 56 fi 57 58 if [ ! -x ${GIT} ]; then 59 echo "[-] ${GIT} not found" >&2 60 return 1 61 fi 62 63 if [ ${SIGNED} -gt 0 ]; then 64 if [ -z "${SSH_KEY}" ]; then 65 echo "[-] Signed build request, but SSH_KEY not specified" >&2 66 return 1 67 fi 68 69 if [ ! -f "${SSH_KEY}" ]; then 70 echo "[-] SSH key \"${SSH_KEY}\" not found" >&2 71 return 1 72 fi 73 74 if [ ! -x "${SSH_KEYGEN}" ]; then 75 echo "[-] ${SSH_KEYGEN} not found" >&2 76 return 1 77 fi 78 fi 79 80 if [ ${QUARTERLY} -eq 1 ]; then 81 if [ -z "${QUARTERLY_BRANCH_NAME}" ]; then 82 echo "[-] QUARTERLY_BRANCH_NAME must be set" >&2 83 return 1 84 fi 85 fi 86 87 if [ ${PUBLISH_INSTALLERS} -gt 0 ]; then 88 if [ -z "${INSTALLER_PUBDIR}" ]; then 89 echo "[-] Installer publishing requested, but INSTALLER_PUBDIR not specified" >&2 90 return 1 91 fi 92 93 if [ ! -d "${INSTALLER_PUBDIR}" ]; then 94 echo "[-] INSTALLER_PUBDIR \"${INSTALLER_PUBDIR}\" not found" >&2 95 return 1 96 fi 97 fi 98 99 if [ ${PUBLISH_UPDATE} -gt 0 ]; then 100 if [ -z "${UPDATE_PUBDIR}" ]; then 101 echo "[-] Update publishing requested, but UPDATE_PUBDIR not specified" >&2 102 return 1 103 fi 104 105 if [ ! -d "${UPDATE_PUBDIR}" ]; then 106 echo "[-] UPDATE_PUBDIR \"${UPDATE_PUBDIR}\" not found" >&2 107 return 1 108 fi 109 fi 110 111 return 0 112 } 113 114 function lock_build() { 115 touch ${LOCKFILE} 116 return ${?} 117 } 118 119 function unlock_build() { 120 rm -f ${LOCKFILE} 121 return ${?} 122 } 123 124 function prep_build() { 125 if [ ! -z "${OBJDIR_TMPFS}" ]; then 126 if [ ${BUILD_INSTALLERS} -gt 0 ] && [ ${PUBLISH_INSTALLERS} -gt 0 ]; then 127 umount -f ${OBJDIR_TMPFS} || true 128 mkdir -p ${OBJDIR_TMPFS} 129 mount -t tmpfs tmpfs ${OBJDIR_TMPFS} 130 fi 131 fi 132 } 133 134 function get_quarterly_branch_name() { 135 echo "${QUARTERLY_BRANCH_NAME}-$(date +%Y)q$(( ($(date +%-m)-1)/3+1 ))" 136 } 137 138 function cleanup() { 139 local shouldexit 140 local res 141 142 if [ ! -z "${OBJDIR_TMPFS}" ]; then 143 if [ ${BUILD_INSTALLERS} -gt 0 ] && [ ${PUBLISH_INSTALLERS} -gt 0 ]; then 144 umount ${OBJDIR_TMPFS} 145 rm -rf ${OBJDIR_TMPFS} 146 fi 147 fi 148 149 if [ ! -z "${UPDATE_OUTPUTDIR}" ] && [ -d ${UPDATE_OUTPUTDIR} ]; then 150 find ${UPDATE_OUTPUTDIR} -type f | xargs rm -f 151 fi 152 153 unlock_build 154 res=${?} 155 if [ ${res} -gt 0 ]; then 156 return ${res} 157 fi 158 159 shouldexit="${1}" 160 if [ ! -z "${shouldexit}" ]; then 161 exit ${shouldexit} 162 fi 163 164 return 0 165 } 166 167 function get_objdir() { 168 if [ ! -z "${OBJDIR_TMPFS}" ]; then 169 echo ${OBJDIR_TMPFS} 170 return 0 171 fi 172 173 make -C ${SRCDIR} -V .OBJDIR buildworld 174 return ${?} 175 } 176 177 function get_pkgbase_repodir() { 178 local res 179 180 dir=$(make -C ${SRCDIR} -V OBJROOT packages) 181 res=${?} 182 if [ ${res} -gt 0 ]; then 183 return ${?} 184 fi 185 186 echo "${dir}/repo" 187 188 return ${?} 189 } 190 191 function get_latest_build_id() { 192 local publishdir 193 local vernum 194 195 publishdir="${1}" 196 if [ -z "${publishdir}" ]; then 197 echo "[-] ${0}: specify publish directory" >&2 198 return 0 199 fi 200 201 if [ -f ${publishdir}/index.txt ]; then 202 vernum=$(cat ${publishdir}/index.txt) 203 echo ${vernum} 204 return ${vernum} 205 fi 206 207 echo 1 208 return 0 209 } 210 211 function get_next_build_id() { 212 local vernum 213 214 vernum=$(get_latest_build_id "${1}") 215 if [ ${vernum} -eq 0 ]; then 216 echo 0 217 return 0 218 fi 219 220 vernum=$((${vernum} + 1)) 221 echo ${vernum} 222 return 0 223 } 224 225 function cache_build_id() { 226 local fulldir 227 local pubdir 228 local vernum 229 local res 230 231 pubdir="${1}" 232 vernum=${2} 233 fulldir="${3}" 234 235 if [ -z "${pubdir}" ] || [ -z "${vernum}" ]; then 236 return 1 237 fi 238 239 echo -n ${vernum} > ${pubdir}/index.txt 240 chmod 755 ${pubdir}/index.txt 241 242 if [ ! -z "${fulldir}" ]; then 243 ln -sf ${fulldir} ${pubdir}/LATEST 244 res=${?} 245 if [ ${res} -gt 0 ]; then 246 return ${res} 247 fi 248 fi 249 250 return 0 251 } 252 253 function sign_file() { 254 local f 255 256 f="${1}" 257 258 if [ -z "${f}" ] || [ ! -f ${f} ]; then 259 return 1 260 fi 261 262 yes | ${SSH_KEYGEN} -Y sign -f ${SSH_KEY} -n file ${f} 263 return ${?} 264 } 265 266 function sign_directory() { 267 local pubdir 268 local res 269 local f 270 271 pubdir="${1}" 272 if [ -z "${pubdir}" ]; then 273 echo "[-] ${0}: Specify publish directory" >&2 274 return 1 275 fi 276 277 ( 278 cd ${pubir} 279 for f in $(find ${pubdir} -maxdepth 1 -type f -a ! -name \*.sig); do 280 sign_file ${f} 281 res=${?} 282 if [ ${res} -gt 0 ]; then 283 exit ${res} 284 fi 285 done 286 ) 287 288 return 0 289 }