1cb9d4bb1SMuhammad Moinur Rahman# SPDX-License-Identifier: BSD-2-Clause 2cb9d4bb1SMuhammad Moinur Rahman# 3cb9d4bb1SMuhammad Moinur Rahman# Copyright (c) 2024 The FreeBSD Foundation 4cb9d4bb1SMuhammad Moinur Rahman# 5cb9d4bb1SMuhammad Moinur Rahman# This software was developed by Cybermancer Infosec <bofh@FreeBSD.org> 6cb9d4bb1SMuhammad Moinur Rahman# under sponsorship from the FreeBSD Foundation. 7cb9d4bb1SMuhammad Moinur Rahman# 8cb9d4bb1SMuhammad Moinur Rahman# Makefile for CI testing. 9cb9d4bb1SMuhammad Moinur Rahman# 10cb9d4bb1SMuhammad Moinur Rahman# User-driven targets: 11cb9d4bb1SMuhammad Moinur Rahman# ci: Run CI tests. Currently only smoke tests are supported. 12cb9d4bb1SMuhammad Moinur Rahman# ci-smokeit: Currently same as ci. 13cb9d4bb1SMuhammad Moinur Rahman# 14cb9d4bb1SMuhammad Moinur Rahman# Variables affecting the build process: 15cb9d4bb1SMuhammad Moinur Rahman# TARGET/TARGET_ARCH: architecture of built release (default: same as build host) 16cb9d4bb1SMuhammad Moinur Rahman# KERNELCONF: kernel configuration to use 17cb9d4bb1SMuhammad Moinur Rahman# USE_QEMU: Use QEMU for testing rather than bhyve 18cb9d4bb1SMuhammad Moinur Rahman# 19cb9d4bb1SMuhammad Moinur Rahman 20cb9d4bb1SMuhammad Moinur RahmanWORLDDIR?= ${.CURDIR}/../.. 21cb9d4bb1SMuhammad Moinur RahmanRELEASEDIR= ${WORLDDIR}/release 22cb9d4bb1SMuhammad Moinur RahmanMAKECONF?= /dev/null 23cb9d4bb1SMuhammad Moinur RahmanSRCCONF?= /dev/null 24cb9d4bb1SMuhammad Moinur Rahman_MEMORY!=sysctl -n hw.physmem 2>/dev/null 25cb9d4bb1SMuhammad Moinur RahmanPARALLEL_JOBS!=sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null 26cb9d4bb1SMuhammad Moinur RahmanTOTAL_MEMORY!=expr ${_MEMORY} / 1073741824 27cb9d4bb1SMuhammad Moinur RahmanKERNCONF?= GENERIC 28cb9d4bb1SMuhammad Moinur RahmanLOCALBASE?= /usr/local 29cb9d4bb1SMuhammad Moinur Rahman 30cb9d4bb1SMuhammad Moinur Rahman.if !defined(TARGET) || empty(TARGET) 31cb9d4bb1SMuhammad Moinur RahmanTARGET= ${MACHINE} 32cb9d4bb1SMuhammad Moinur Rahman.endif 33cb9d4bb1SMuhammad Moinur Rahman.if !defined(TARGET_ARCH) || empty(TARGET_ARCH) 34cb9d4bb1SMuhammad Moinur Rahman.if ${TARGET} == ${MACHINE} 35cb9d4bb1SMuhammad Moinur RahmanTARGET_ARCH= ${MACHINE_ARCH} 36cb9d4bb1SMuhammad Moinur Rahman.else 37cb9d4bb1SMuhammad Moinur RahmanTARGET_ARCH= ${TARGET} 38cb9d4bb1SMuhammad Moinur Rahman.endif 39cb9d4bb1SMuhammad Moinur Rahman.endif 40cb9d4bb1SMuhammad Moinur RahmanIMAKE= ${MAKE} TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} 41cb9d4bb1SMuhammad Moinur Rahman 42cb9d4bb1SMuhammad Moinur Rahman.if defined(CROSS_TOOLCHAIN) || !empty(CROSS_TOOLCHAIN) 43cb9d4bb1SMuhammad Moinur RahmanCROSS_TOOLCHAIN_PARAM= "CROSS_TOOLCHAIN=${CROSS_TOOLCHAIN}" 44cb9d4bb1SMuhammad Moinur Rahman.endif 45cb9d4bb1SMuhammad Moinur Rahman 46cb9d4bb1SMuhammad Moinur Rahman# Define OSRELEASE by using newvers.sh 47cb9d4bb1SMuhammad Moinur Rahman.if !defined(OSRELEASE) || empty(OSRELEASE) 48cb9d4bb1SMuhammad Moinur Rahman.for _V in TYPE BRANCH REVISION 49cb9d4bb1SMuhammad Moinur Rahman. if !defined(${_V}) || empty(${_V}) 50cb9d4bb1SMuhammad Moinur Rahman${_V}!= eval $$(awk '/^${_V}=/{print}' ${.CURDIR}/../../sys/conf/newvers.sh); echo $$${_V} 51cb9d4bb1SMuhammad Moinur Rahman. endif 52cb9d4bb1SMuhammad Moinur Rahman.endfor 53cb9d4bb1SMuhammad Moinur Rahman.for _V in ${TARGET_ARCH} 54cb9d4bb1SMuhammad Moinur Rahman.if !empty(TARGET:M${_V}) 55cb9d4bb1SMuhammad Moinur RahmanOSRELEASE= ${TYPE}-${REVISION}-${BRANCH}-${TARGET} 56cb9d4bb1SMuhammad Moinur RahmanVOLUME_LABEL= ${REVISION:C/[.-]/_/g}_${BRANCH:C/[.-]/_/g}_${TARGET} 57cb9d4bb1SMuhammad Moinur Rahman.else 58cb9d4bb1SMuhammad Moinur RahmanOSRELEASE= ${TYPE}-${REVISION}-${BRANCH}-${TARGET}-${TARGET_ARCH} 59cb9d4bb1SMuhammad Moinur RahmanVOLUME_LABEL= ${REVISION:C/[.-]/_/g}_${BRANCH:C/[.-]/_/g}_${TARGET_ARCH} 60cb9d4bb1SMuhammad Moinur Rahman.endif 61cb9d4bb1SMuhammad Moinur Rahman.endfor 62cb9d4bb1SMuhammad Moinur Rahman.endif 63cb9d4bb1SMuhammad Moinur Rahman 64cb9d4bb1SMuhammad Moinur Rahman.if exists(${.CURDIR}/tools/ci.conf) && !defined(CICONF) 65cb9d4bb1SMuhammad Moinur RahmanCICONF?= ${.CURDIR}/tools/ci.conf 66cb9d4bb1SMuhammad Moinur Rahman.endif 67cb9d4bb1SMuhammad Moinur RahmanSWAPSIZE?= 1g 68cb9d4bb1SMuhammad Moinur RahmanVMFS?= ufs 69cb9d4bb1SMuhammad Moinur RahmanFORMAT= raw 70cb9d4bb1SMuhammad Moinur RahmanCIIMAGE= ci-${OSRELEASE}-${GITREV}-${KERNCONF}.${FORMAT} 71cb9d4bb1SMuhammad Moinur RahmanVMSIZE?= 6g 72cb9d4bb1SMuhammad Moinur RahmanCITYPE?= 73cb9d4bb1SMuhammad Moinur RahmanTEST_VM_NAME= ci-${OSRELEASE}-${GITREV}-${KERNCONF} 74cb9d4bb1SMuhammad Moinur Rahman.if ${TOTAL_MEMORY} >= 16 75cb9d4bb1SMuhammad Moinur RahmanVM_MEM!=expr ${TOTAL_MEMORY} / 2 76cb9d4bb1SMuhammad Moinur Rahman.elif ${TOTAL_MEMORY} >=4 77cb9d4bb1SMuhammad Moinur RahmanVM_MEM=${TOTAL_MEMORY} 78cb9d4bb1SMuhammad Moinur Rahman.else 79cb9d4bb1SMuhammad Moinur Rahmanecho "Please increase the memory to at least 4GB" 80cb9d4bb1SMuhammad Moinur Rahmanexit 0 81cb9d4bb1SMuhammad Moinur Rahman.endif 82cb9d4bb1SMuhammad Moinur RahmanVM_MEM_SIZE?=${VM_MEM}g 83cb9d4bb1SMuhammad Moinur RahmanTIMEOUT_MS?=5400000 84cb9d4bb1SMuhammad Moinur RahmanTIMEOUT=$$((${TIMEOUT_MS} / 1000)) 85cb9d4bb1SMuhammad Moinur RahmanTIMEOUT_EXPECT=$$((${TIMEOUT} - 60)) 86cb9d4bb1SMuhammad Moinur RahmanTIMEOUT_VM=$$((${TIMEOUT_EXPECT} - 120)) 87cb9d4bb1SMuhammad Moinur Rahman.if exists(${.CURDIR}/Makefile.${TARGET_ARCH}) 88cb9d4bb1SMuhammad Moinur Rahman. include "${.CURDIR}/Makefile.${TARGET_ARCH}" 89cb9d4bb1SMuhammad Moinur Rahman.endif 90cb9d4bb1SMuhammad Moinur Rahman.if ${TARGET_ARCH} != ${MACHINE_ARCH} 91cb9d4bb1SMuhammad Moinur Rahman.if ( ${TARGET_ARCH} != "i386" ) || ( ${MACHINE_ARCH} != "amd64" ) 92cb9d4bb1SMuhammad Moinur RahmanQEMUSTATIC=/usr/local/bin/qemu-${QEMU_ARCH}-static 93cb9d4bb1SMuhammad Moinur RahmanQEMUTGT=portinstall-qemu 94cb9d4bb1SMuhammad Moinur Rahman.endif 95cb9d4bb1SMuhammad Moinur Rahman.endif 96cb9d4bb1SMuhammad Moinur RahmanQEMUTGT?= 97cb9d4bb1SMuhammad Moinur RahmanQEMU_DEVICES?=-device virtio-blk,drive=hd0 98cb9d4bb1SMuhammad Moinur RahmanQEMU_EXTRA_PARAM?= 99cb9d4bb1SMuhammad Moinur RahmanQEMU_MACHINE?=virt 100cb9d4bb1SMuhammad Moinur RahmanQEMUBIN=/usr/local/bin/qemu-system-${QEMU_ARCH} 101cb9d4bb1SMuhammad Moinur Rahman.if ${PARALLEL_JOBS} >= ${QEMU_MAX_CPU_COUNT} 102cb9d4bb1SMuhammad Moinur RahmanQEMU_CPU_COUNT=${QEMU_MAX_CPU_COUNT} 103cb9d4bb1SMuhammad Moinur Rahman.else 104cb9d4bb1SMuhammad Moinur RahmanQEMU_CPU_COUNT=${PARALLEL_JOBS} 105cb9d4bb1SMuhammad Moinur Rahman.endif 106cb9d4bb1SMuhammad Moinur Rahman.if ${VM_MEM} >= ${QEMU_MAX_MEM_SIZE} 107cb9d4bb1SMuhammad Moinur RahmanVM_MEM_SIZE=${QEMU_MAX_MEM_SIZE}g 108cb9d4bb1SMuhammad Moinur Rahman.else 109cb9d4bb1SMuhammad Moinur RahmanVM_MEM_SIZE=${VM_MEM}g 110cb9d4bb1SMuhammad Moinur Rahman.endif 111cb9d4bb1SMuhammad Moinur RahmanKLDVMMISLOADED!=kldload -q -n vmm 2>/dev/null && echo "1" || echo "0" 112cb9d4bb1SMuhammad Moinur Rahman.if ${KLDVMMISLOADED} == "0" 113cb9d4bb1SMuhammad Moinur RahmanUSE_QEMU?=1 114cb9d4bb1SMuhammad Moinur Rahman.endif 115cb9d4bb1SMuhammad Moinur RahmanKLDFILEMONISLOADED!=kldload -q -n filemon 2>/dev/null && echo "1" || echo "0" 116cb9d4bb1SMuhammad Moinur Rahman.if ${KLDFILEMONISLOADED} == "1" 117cb9d4bb1SMuhammad Moinur RahmanMETAMODE?=-DWITH_META_MODE 118cb9d4bb1SMuhammad Moinur Rahman.endif 119cb9d4bb1SMuhammad Moinur Rahman 120cb9d4bb1SMuhammad Moinur RahmanCLEANFILES= ${CIIMAGE} ci.img 121cb9d4bb1SMuhammad Moinur RahmanCLEANDIRS= ci-buildimage 122cb9d4bb1SMuhammad Moinur Rahman 123cb9d4bb1SMuhammad Moinur Rahmanportinstall: portinstall-pkg portinstall-qemu portinstall-expect portinstall-${TARGET_ARCH:tl} .PHONY 124cb9d4bb1SMuhammad Moinur Rahman 125cb9d4bb1SMuhammad Moinur Rahmanportinstall-pkg: .PHONY 126cb9d4bb1SMuhammad Moinur Rahman.if !exists(/usr/local/sbin/pkg-static) 127cb9d4bb1SMuhammad Moinur Rahman env ASSUME_ALWAYS_YES=yes pkg bootstrap 128cb9d4bb1SMuhammad Moinur Rahman.endif 129cb9d4bb1SMuhammad Moinur Rahman 130cb9d4bb1SMuhammad Moinur Rahmanportinstall-qemu: portinstall-pkg .PHONY 131cb9d4bb1SMuhammad Moinur Rahman.if !exists(/usr/local/bin/qemu-${TARGET_ARCH}-static) 132cb9d4bb1SMuhammad Moinur Rahman env ASSUME_ALWAYS_YES=yes pkg install emulators/qemu-user-static 133cb9d4bb1SMuhammad Moinur Rahman.endif 134cb9d4bb1SMuhammad Moinur Rahman.if !exists(/usr/local/bin/qemu-system-${QEMU_ARCH}) 135cb9d4bb1SMuhammad Moinur Rahman env ASSUME_ALWAYS_YES=yes pkg install emulators/qemu@nox11 136cb9d4bb1SMuhammad Moinur Rahman.endif 137cb9d4bb1SMuhammad Moinur Rahman 138cb9d4bb1SMuhammad Moinur Rahmanportinstall-expect: portinstall-pkg .PHONY 139cb9d4bb1SMuhammad Moinur Rahman.if !exists(/usr/local/bin/expect) 140cb9d4bb1SMuhammad Moinur Rahman env ASSUME_ALWAYS_YES=yes pkg install lang/expect 141cb9d4bb1SMuhammad Moinur Rahman.endif 142cb9d4bb1SMuhammad Moinur Rahman 143cb9d4bb1SMuhammad Moinur Rahmanbeforeclean: .PHONY 144cb9d4bb1SMuhammad Moinur Rahman chflags -R noschg . 145cb9d4bb1SMuhammad Moinur Rahman 146cb9d4bb1SMuhammad Moinur Rahman.include <bsd.obj.mk> 147cb9d4bb1SMuhammad Moinur Rahmanclean: beforeclean .PHONY 148cb9d4bb1SMuhammad Moinur Rahman 149cb9d4bb1SMuhammad Moinur Rahmanci-buildworld: .PHONY 150*a5f03413SWarner Losh @echo "Building world for ${TARGET_ARCH}" 151*a5f03413SWarner Losh ${IMAKE} -j${PARALLEL_JOBS} -C ${WORLDDIR} ${METAMODE} \ 152*a5f03413SWarner Losh ${CROSS_TOOLCHAIN_PARAM} __MAKE_CONF=${MAKECONF} SRCCONF=${SRCCONF} \ 153*a5f03413SWarner Losh buildworld > ${.CURDIR}/_.${TARGET_ARCH}.${.TARGET} 2>&1 || \ 154*a5f03413SWarner Losh (echo "${.TARGET} failed, check _.${TARGET_ARCH}.${.TARGET} for details" ; false) 155*a5f03413SWarner Losh 156cb9d4bb1SMuhammad Moinur Rahman 157cb9d4bb1SMuhammad Moinur Rahmanci-buildkernel: ci-buildworld-${TARGET_ARCH:tl} .PHONY 158*a5f03413SWarner Losh @echo "Building kenrel for ${TARGET_ARCH"}" 159*a5f03413SWarner Losh ${IMAKE} -j${PARALLEL_JOBS} -C ${WORLDDIR} ${METAMODE} \ 160*a5f03413SWarner Losh ${CROSS_TOOLCHAIN_PARAM} __MAKE_CONF=${MAKECONF} \ 161*a5f03413SWarner Losh SRCCONF=${SRCCONF} buildkernel > ${.CURDIR}/_.${TARGET_ARCH}.${.TARGET} 2>&1 || \ 162*a5f03413SWarner Losh (echo "${.TARGET} failed, check _.${TARGET_ARCH}.${.TARGET} for details" ; false) 163cb9d4bb1SMuhammad Moinur Rahman 164cb9d4bb1SMuhammad Moinur Rahmanci-buildimage: ${QEMUTGT} ci-buildkernel-${TARGET_ARCH:tl} .PHONY 165*a5f03413SWarner Losh @echo "Building ci image for ${TARGET_ARCH"}" 166cb9d4bb1SMuhammad Moinur Rahman mkdir -p ${.OBJDIR}/${.TARGET} 167cb9d4bb1SMuhammad Moinur Rahman env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} SWAPSIZE=${SWAPSIZE} \ 168cb9d4bb1SMuhammad Moinur Rahman QEMUSTATIC=${QEMUSTATIC} CITYPE=${CITYPE} \ 169cb9d4bb1SMuhammad Moinur Rahman ${RELEASEDIR}/scripts/mk-vmimage.sh \ 170cb9d4bb1SMuhammad Moinur Rahman -C ${RELEASEDIR}/tools/vmimage.subr -d ${.OBJDIR}/${.TARGET} -F ${VMFS} \ 171cb9d4bb1SMuhammad Moinur Rahman -i ${.OBJDIR}/ci.img -s ${VMSIZE} -f ${FORMAT} \ 172*a5f03413SWarner Losh -S ${WORLDDIR} -o ${.OBJDIR}/${CIIMAGE} -c ${CICONF} \ 173*a5f03413SWarner Losh > ${.CURDIR}/_.${TARGET_ARCH}.${.TARGET} 2>&1 || \ 174*a5f03413SWarner Losh (echo "${.TARGET} failed, check _.${TARGET_ARCH}.${.TARGET} for details" ; false) 175cb9d4bb1SMuhammad Moinur Rahman touch ${.TARGET} 176cb9d4bb1SMuhammad Moinur Rahman 177cb9d4bb1SMuhammad Moinur Rahmanci-setsmokevar: .PHONY 178cb9d4bb1SMuhammad Moinur RahmanCITYPE=smoke 179cb9d4bb1SMuhammad Moinur Rahman 180cb9d4bb1SMuhammad Moinur Rahmanci-runtest: ci-buildimage-${TARGET_ARCH:tl} portinstall .PHONY 181cb9d4bb1SMuhammad Moinur Rahman.if ${MACHINE} == "amd64" && ( ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" ) && ( !defined(USE_QEMU) || empty(USE_QEMU) ) 182cb9d4bb1SMuhammad Moinur Rahman /usr/sbin/bhyvectl --vm=${TEST_VM_NAME} --destroy || true 183cb9d4bb1SMuhammad Moinur Rahman /usr/sbin/bhyveload -c stdio -m ${VM_MEM_SIZE} -d ${CIIMAGE} ${TEST_VM_NAME} 184cb9d4bb1SMuhammad Moinur Rahman expect -c "set timeout ${TIMEOUT_EXPECT}; \ 185cb9d4bb1SMuhammad Moinur Rahman spawn /usr/bin/timeout -k 60 ${TIMEOUT_VM} /usr/sbin/bhyve \ 186cb9d4bb1SMuhammad Moinur Rahman -c ${PARALLEL_JOBS} -m ${VM_MEM_SIZE} -A -H -P \ 187cb9d4bb1SMuhammad Moinur Rahman -s 0:0,hostbridge \ 188cb9d4bb1SMuhammad Moinur Rahman -s 1:0,lpc \ 189cb9d4bb1SMuhammad Moinur Rahman -s 2:0,virtio-blk,${CIIMAGE} \ 190cb9d4bb1SMuhammad Moinur Rahman -l com1,stdio \ 191cb9d4bb1SMuhammad Moinur Rahman ${TEST_VM_NAME}; \ 192cb9d4bb1SMuhammad Moinur Rahman expect { eof }" 193cb9d4bb1SMuhammad Moinur Rahman /usr/sbin/bhyvectl --vm=${TEST_VM_NAME} --destroy 194cb9d4bb1SMuhammad Moinur Rahman.else 195cb9d4bb1SMuhammad Moinur Rahman timeout -k 60 ${TIMEOUT_VM} ${QEMUBIN} \ 196cb9d4bb1SMuhammad Moinur Rahman -machine ${QEMU_MACHINE} \ 197cb9d4bb1SMuhammad Moinur Rahman -smp ${QEMU_CPU_COUNT} \ 198cb9d4bb1SMuhammad Moinur Rahman -m ${VM_MEM_SIZE} \ 199cb9d4bb1SMuhammad Moinur Rahman -nographic \ 200cb9d4bb1SMuhammad Moinur Rahman -no-reboot \ 201cb9d4bb1SMuhammad Moinur Rahman ${QEMU_EXTRA_PARAM} \ 202cb9d4bb1SMuhammad Moinur Rahman -drive if=none,file=${CIIMAGE},format=raw,id=hd0 \ 203cb9d4bb1SMuhammad Moinur Rahman ${QEMU_DEVICES} 204cb9d4bb1SMuhammad Moinur Rahman.endif 205cb9d4bb1SMuhammad Moinur Rahman 206cb9d4bb1SMuhammad Moinur Rahmanci-checktarget: .PHONY 207cb9d4bb1SMuhammad Moinur Rahman.if ${TARGET_ARCH} != "aarch64" && \ 208cb9d4bb1SMuhammad Moinur Rahman ${TARGET_ARCH} != "amd64" && \ 209cb9d4bb1SMuhammad Moinur Rahman ${TARGET_ARCH} != "armv7" && \ 210cb9d4bb1SMuhammad Moinur Rahman ${TARGET_ARCH} != "powerpc64" && \ 211cb9d4bb1SMuhammad Moinur Rahman ${TARGET_ARCH} != "powerpc64le" && \ 212cb9d4bb1SMuhammad Moinur Rahman ${TARGET_ARCH} != "riscv64" 213cb9d4bb1SMuhammad Moinur Rahman @false 214cb9d4bb1SMuhammad Moinur Rahman.ERROR: 215cb9d4bb1SMuhammad Moinur Rahman @echo "Error: ${TARGET_ARCH} is not supported on ${TYPE} ${REVISION} ${BRANCH}" 216cb9d4bb1SMuhammad Moinur Rahman.endif 217cb9d4bb1SMuhammad Moinur Rahman 218cb9d4bb1SMuhammad Moinur Rahmanci-smokeit: ci-setsmokevar ci-checktarget .WAIT ci-runtest-${TARGET_ARCH:tl} .PHONY 219cb9d4bb1SMuhammad Moinur Rahman 220cb9d4bb1SMuhammad Moinur Rahmanci: ci-smokeit .PHONY 221cb9d4bb1SMuhammad Moinur Rahman 222cb9d4bb1SMuhammad Moinur Rahman.include "${RELEASEDIR}/Makefile.inc1" 223