1+ #! /usr/bin/env bash
2+
3+ set -eo pipefail
4+
5+ # Include the utils library
6+ source scripts/lib_utils.sh
7+
8+ CLI=" docker"
9+
10+ MANIFEST_FILE=" manifest.yaml"
11+
12+ IMAGE_TAG=" latest"
13+ IMAGE_FORMAT=" oci"
14+ UBUNTU_VERSION=" 24.04"
15+ APP_UID=" 1000"
16+
17+ BUILD_DIR=" ./build"
18+
19+ check_for_manifest (){
20+ if [[ ! -f " $MANIFEST_FILE " ]]; then
21+ log_error " Manifest file not found"
22+ exit 1
23+ fi
24+ }
25+
26+ retrieve_name_from_manifest (){
27+ local name
28+ name=$( yq e ' .name' $MANIFEST_FILE )
29+ echo $name
30+ }
31+
32+ retrieve_registry_from_manifest (){
33+ local registry
34+ registry=$( yq e ' .registry' $MANIFEST_FILE )
35+ echo $registry
36+ }
37+
38+
39+ clean_build_dir (){
40+ if [[ -d " ${BUILD_DIR} " ]]; then
41+ log_trace " Removing existing build directory"
42+ rm -rf " ${BUILD_DIR} "
43+ fi
44+ mkdir -p " ${BUILD_DIR} "
45+ }
46+
47+ hadolint_validate (){
48+ local hadolint_exec
49+ local hadolint_exit_code
50+ log_info " Validating Dockerfile with hadolint"
51+ ${CLI} pull -q ghcr.io/hadolint/hadolint:latest > /dev/null
52+ log_trace " $( ${CLI} run --rm -i hadolint/hadolint:latest hadolint -v) "
53+
54+ set +e
55+ hadolint_exec=$(
56+ ${CLI} run --rm -i hadolint/hadolint:latest < Containerfile \
57+ 2>&1
58+ )
59+ hadolint_exit_code=$?
60+ set -e
61+ if [[ $hadolint_exit_code -ne 0 ]]; then
62+ echo -e " ${WHITE_GRAY}${hadolint_exec}${NC} "
63+ log_error " Hadolint validation failed"
64+ exit 1
65+ else
66+ log_success " Hadolint validation passed"
67+ fi
68+ }
69+
70+ buildah_build (){
71+ local buildah_exec
72+ local buildah_exit_code
73+ local buildah_args
74+ local manifest_args
75+ log_info " Build Containerfile for ${IMAGE_NAME} :${IMAGE_TAG} "
76+ log_trace " $( buildah --version) "
77+
78+
79+ # Extract build args from manifest
80+ buildah_args=()
81+ for arg in $( yq e ' .build.args[]' $MANIFEST_FILE ) ; do
82+ buildah_args+=" --build-arg ${arg} "
83+ done
84+
85+ log_trace " Buildah args: ${buildah_args} "
86+ set +e
87+ buildah_exec=$(
88+ buildah build \
89+ --squash \
90+ --pull-always \
91+ --format ${IMAGE_FORMAT} \
92+ ${buildah_args} \
93+ --tag docker-daemon:${IMAGE_NAME} :${IMAGE_TAG} \
94+ . \
95+ 2>&1
96+ )
97+ buildah_exit_code=$?
98+ set -e
99+ if [[ $buildah_exit_code -ne 0 ]]; then
100+ log_error " Build failed"
101+ log_error " ${buildah_exec} "
102+ exit 1
103+ else
104+ log_success " Build completed successfully"
105+ fi
106+ }
107+
108+ podman_save_image_to_tar (){
109+ local podman_exec
110+ local podman_exit_code
111+ log_info " Saving image to tar ${IMAGE_NAME} :${IMAGE_TAG} "
112+ log_trace " $( podman --version) "
113+
114+ set +e
115+ podman_exec=$(
116+ ${CLI} save \
117+ --output ${BUILD_DIR} /${IMAGE_NAME} -${IMAGE_TAG} .tar \
118+ ${IMAGE_NAME} :${IMAGE_TAG} \
119+ 2>&1
120+ )
121+ podman_exit_code=$?
122+ set -e
123+ if [[ $podman_exit_code -ne 0 ]]; then
124+ echo -e " ${WHITE_GRAY}${podman_exec}${NC} "
125+ log_error " Saving image to tar failed"
126+ exit 1
127+ else
128+ log_success " Image saved to ${BUILD_DIR} /${IMAGE_NAME} -${IMAGE_TAG} .tar"
129+ fi
130+ }
131+
132+ docker_save_image_to_tar (){
133+ local docker_exec
134+ local docker_exit_code
135+ log_info " Saving image to tar ${IMAGE_NAME} :${IMAGE_TAG} "
136+ log_trace " $( docker --version) "
137+
138+ set +e
139+ docker_exec=$(
140+ ${CLI} save \
141+ --output ${BUILD_DIR} /${IMAGE_NAME} -${IMAGE_TAG} .tar \
142+ ${IMAGE_NAME} :${IMAGE_TAG} \
143+ 2>&1
144+ )
145+ docker_exit_code=$?
146+ set -e
147+ if [[ $docker_exit_code -ne 0 ]]; then
148+ echo -e " ${WHITE_GRAY}${docker_exec}${NC} "
149+ log_error " Saving image to tar failed"
150+ exit 1
151+ else
152+ log_success " Image saved to ${BUILD_DIR} /${IMAGE_NAME} -${IMAGE_TAG} .tar"
153+ fi
154+ }
155+
156+ dive_scan () {
157+ local dive_scan
158+ log_info " Running dive scan on ${IMAGE_NAME} :${IMAGE_TAG} "
159+ log_trace " $( dive --version) "
160+
161+ set +e
162+ dive_scan=$( \
163+ dive \
164+ --ci \
165+ --source=${CLI} \
166+ ${IMAGE_NAME} :${IMAGE_TAG} \
167+ 2>&1 \
168+ )
169+ set -e
170+
171+ if [[ $dive_scan == * " FAIL" * ]]; then
172+ echo -e " ${WHITE_GRAY}${dive_scan}${NC} "
173+ log_error " Dive scan failed"
174+ exit 1
175+ else
176+ log_success " Dive scan passed"
177+ fi
178+ }
179+
180+ trivy_scan () {
181+
182+ local trivy_scan_exec
183+ local trivy_scan_exit_code
184+
185+ log_info " Running trivy scan on ${IMAGE_NAME} :${IMAGE_TAG} "
186+ log_trace " $( trivy --version) "
187+
188+ set +e
189+ trivy_scan_exec=$( \
190+ trivy image \
191+ --input ${BUILD_DIR} /${IMAGE_NAME} -${IMAGE_TAG} .tar \
192+ --format github \
193+ --severity HIGH,CRITICAL \
194+ --exit-code 2 \
195+ ${IMAGE_NAME} :${IMAGE_TAG} \
196+ 2>&1
197+ )
198+ # Detect exit code
199+ trivy_scan_exit_code=$?
200+ set -e
201+ if [[ $trivy_scan_exit_code -eq 2 ]]; then
202+ echo -e " ${WHITE_GRAY}${trivy_scan_exec}${NC} "
203+ log_error " Trivy scan failed"
204+ exit 1
205+ elif [[ $trivy_scan_exit_code -eq 1 ]]; then
206+ echo -e " ${WHITE_GRAY}${trivy_scan_exec}${NC} "
207+ log_error " Trivy scan error"
208+ else
209+ log_success " Trivy scan passed"
210+ fi
211+ }
212+
213+ # Main
214+ clean_build_dir
215+ check_for_manifest # Check for manifest file existence\
216+ IMAGE_NAME=$( retrieve_name_from_manifest) # Retrieve image name from manifest
217+
218+ log_info " Starting build process"
219+ log_trace " CLI: ${CLI} "
220+ log_trace " IMAGE_NAME: ${IMAGE_NAME} "
221+ log_trace " IMAGE_TAG: ${IMAGE_TAG} "
222+ log_trace " IMAGE_FORMAT: ${IMAGE_FORMAT} "
223+
224+
225+ hadolint_validate # Validate/Lint Containerfile
226+ buildah_build # Build Containerfile
227+
228+ if [[ $CLI == " podman" ]]; then
229+ podman_save_image_to_tar # Save image to tar (for trivy scan)
230+ elif [[ $CLI == " docker" ]]; then
231+ docker_save_image_to_tar # Save image to tar (for trivy scan)
232+ else
233+ log_error " Invalid CLI"
234+ exit 1
235+ fi
236+
237+ dive_scan # Filesystem scan and analysis
238+ trivy_scan # Vulnerability scan
239+
240+ # Deploy to registry with skopeo using tags in manifest
241+ registry=$( retrieve_registry_from_manifest)
242+ skopeo copy docker-daemon:${IMAGE_NAME} :${IMAGE_TAG} docker://${registry} :${IMAGE_TAG}
0 commit comments