Add online image verification policy and CI-enforced zip checks
This commit is contained in:
@@ -25,6 +25,7 @@ MUST:
|
|||||||
- Pinna images till explicit version eller digest.
|
- Pinna images till explicit version eller digest.
|
||||||
- Inte använda `:latest`.
|
- Inte använda `:latest`.
|
||||||
- Hålla volymer snäva (`/DATA/AppData/$AppID/...`).
|
- Hålla volymer snäva (`/DATA/AppData/$AppID/...`).
|
||||||
|
- Vid förslag/byte av `image:` måste imagen verifieras online (manifest/tag finns i registry) innan merge.
|
||||||
|
|
||||||
SHOULD:
|
SHOULD:
|
||||||
- `security_opt: ["no-new-privileges:true"]`
|
- `security_opt: ["no-new-privileges:true"]`
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ set -euo pipefail
|
|||||||
|
|
||||||
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
|
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
push_mode=0
|
push_mode=0
|
||||||
|
strict_image_check=0
|
||||||
positional=()
|
positional=()
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
@@ -11,6 +12,10 @@ while [[ $# -gt 0 ]]; do
|
|||||||
push_mode=1
|
push_mode=1
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--strict-images)
|
||||||
|
strict_image_check=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
# handled below via usage
|
# handled below via usage
|
||||||
positional+=("$1")
|
positional+=("$1")
|
||||||
@@ -36,11 +41,14 @@ usage() {
|
|||||||
cat <<USAGE
|
cat <<USAGE
|
||||||
Usage: $0 [output_dir] [zip_name]
|
Usage: $0 [output_dir] [zip_name]
|
||||||
$0 --push [output_dir] [zip_name]
|
$0 --push [output_dir] [zip_name]
|
||||||
|
$0 --strict-images [output_dir] [zip_name]
|
||||||
|
$0 --push --strict-images [output_dir] [zip_name]
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
$0
|
$0
|
||||||
$0 ./dist zima-apps-main.zip
|
$0 ./dist zima-apps-main.zip
|
||||||
$0 --push
|
$0 --push
|
||||||
|
$0 --strict-images
|
||||||
USAGE
|
USAGE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +62,10 @@ if ! command -v zip >/dev/null 2>&1; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${CI:-}" == "true" || "${GITEA_ACTIONS:-}" == "true" ]]; then
|
||||||
|
strict_image_check=1
|
||||||
|
fi
|
||||||
|
|
||||||
required_root_files=(
|
required_root_files=(
|
||||||
"category-list.json"
|
"category-list.json"
|
||||||
"recommend-list.json"
|
"recommend-list.json"
|
||||||
@@ -72,6 +84,81 @@ if [[ ! -d "$repo_root/Apps" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
extract_images_from_compose() {
|
||||||
|
local compose_file="$1"
|
||||||
|
awk '
|
||||||
|
/^[[:space:]]*image:[[:space:]]*/ {
|
||||||
|
line=$0
|
||||||
|
sub(/^[[:space:]]*image:[[:space:]]*/, "", line)
|
||||||
|
sub(/[[:space:]]+#.*/, "", line)
|
||||||
|
gsub(/^["'"'"']|["'"'"']$/, "", line)
|
||||||
|
if (line != "") print line
|
||||||
|
}
|
||||||
|
' "$compose_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_images_online() {
|
||||||
|
local -a images=()
|
||||||
|
local -a missing=()
|
||||||
|
local compose_file app_id
|
||||||
|
|
||||||
|
while IFS= read -r compose_file; do
|
||||||
|
app_id="$(basename "$(dirname "$compose_file")")"
|
||||||
|
if [[ "$app_id" == "_template" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r image_ref; do
|
||||||
|
[[ -z "$image_ref" ]] && continue
|
||||||
|
images+=("$image_ref")
|
||||||
|
done < <(extract_images_from_compose "$compose_file")
|
||||||
|
done < <(find "$repo_root/Apps" -type f -name 'docker-compose.yaml' | sort)
|
||||||
|
|
||||||
|
if [[ ${#images[@]} -eq 0 ]]; then
|
||||||
|
echo "WARN: no images found to verify"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mapfile -t images < <(printf '%s\n' "${images[@]}" | sort -u)
|
||||||
|
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "WARN: docker is not installed; skipping online image verification"
|
||||||
|
if [[ "$strict_image_check" -eq 1 ]]; then
|
||||||
|
echo "ERROR: strict image verification is enabled (CI/Gitea or --strict-images)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Verifying ${#images[@]} image(s) online..."
|
||||||
|
for image_ref in "${images[@]}"; do
|
||||||
|
if docker manifest inspect "$image_ref" >/dev/null 2>&1; then
|
||||||
|
echo "OK: $image_ref"
|
||||||
|
else
|
||||||
|
echo "WARN: image not found or inaccessible: $image_ref"
|
||||||
|
missing+=("$image_ref")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${#missing[@]} -gt 0 ]]; then
|
||||||
|
echo
|
||||||
|
echo "Image verification warnings:"
|
||||||
|
for image_ref in "${missing[@]}"; do
|
||||||
|
echo " - $image_ref"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$strict_image_check" -eq 1 ]]; then
|
||||||
|
echo
|
||||||
|
echo "ERROR: strict image verification is enabled and one or more images are missing."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! verify_images_online; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
is_git_repo=0
|
is_git_repo=0
|
||||||
if git -C "$repo_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
if git -C "$repo_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
is_git_repo=1
|
is_git_repo=1
|
||||||
|
|||||||
Reference in New Issue
Block a user