diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index cab51f91..ac1c93cc 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -62,6 +62,7 @@ jobs: sitectl_drupal_image_tags: ${{ steps.plan.outputs.sitectl_drupal_image_tags }} sitectl_isle_libops_image_tags: ${{ steps.plan.outputs.sitectl_isle_libops_image_tags }} sitectl_isle_images: ${{ steps.plan.outputs.sitectl_isle_images }} + sitectl_create_smoke_matrix: ${{ steps.plan.outputs.sitectl_create_smoke_matrix }} steps: - uses: "actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10" # v6 with: @@ -109,14 +110,65 @@ jobs: ./ci/image-metadata.sh first-tag "$1" "$mode" "$FALLBACK_TAG" } + planned_tag_assignment() { + local service="$1" + local image="$2" + if grep -Fq "\"${image}\"" build-plan.out; then + printf '%s=%s' "$service" "$(first_tag "$image")" + fi + } + + add_smoke_row() { + local plugin="$1" + local packages="$2" + local create_args="$3" + local image_tags="$4" + local images="$5" + if [ -z "${image_tags// }" ]; then + return + fi + smoke_matrix="$( + jq -c \ + --arg plugin "$plugin" \ + --arg packages "$packages" \ + --arg create_args "$create_args" \ + --arg image_tags "$image_tags" \ + --arg images "$images" \ + '. + [{ + "plugin": $plugin, + "packages": $packages, + "create-args": $create_args, + "image-tags": $image_tags, + "images": $images + }]' <<<"$smoke_matrix" + )" + } + + sitectl_wp_image_tags="$(planned_tag_assignment wp wp-php84)" + sitectl_omeka_s_image_tags="$(planned_tag_assignment omeka-s omeka-s-php84)" + sitectl_omeka_classic_image_tags="$(planned_tag_assignment omeka-classic omeka-classic-php84)" + sitectl_ojs_image_tags="$(planned_tag_assignment ojs ojs-php84)" + sitectl_drupal_image_tags="$(planned_tag_assignment drupal drupal-php84)" + sitectl_isle_libops_image_tags="$(planned_tag_assignment drupal islandora-php84)" + sitectl_isle_images="" + + smoke_matrix='[]' + add_smoke_row "wp" "sitectl sitectl-wp" "" "$sitectl_wp_image_tags" "" + add_smoke_row "omeka-s" "sitectl sitectl-omeka-s" "" "$sitectl_omeka_s_image_tags" "" + add_smoke_row "omeka-classic" "sitectl sitectl-omeka-classic" "" "$sitectl_omeka_classic_image_tags" "" + add_smoke_row "ojs" "sitectl sitectl-ojs" "" "$sitectl_ojs_image_tags" "" + add_smoke_row "drupal" "sitectl sitectl-drupal" "" "$sitectl_drupal_image_tags" "" + add_smoke_row "isle" "sitectl sitectl-isle sitectl-drupal" "--template-repo https://github.com/libops/isle --fcrepo off --blazegraph off --isle-file-system-uri private --iiif triplet --iiif-topology disabled --bot-mitigation off" "$sitectl_isle_libops_image_tags" "$sitectl_isle_images" + { - echo "sitectl_wp_image_tags=wp=$(first_tag wp-php84)" - echo "sitectl_omeka_s_image_tags=omeka-s=$(first_tag omeka-s-php84)" - echo "sitectl_omeka_classic_image_tags=omeka-classic=$(first_tag omeka-classic-php84)" - echo "sitectl_ojs_image_tags=ojs=$(first_tag ojs-php84)" - echo "sitectl_drupal_image_tags=drupal=$(first_tag drupal-php84)" - echo "sitectl_isle_libops_image_tags=drupal=$(first_tag islandora-php84) activemq=$(first_tag activemq6) alpaca=$(first_tag alpaca) crayfits=$(first_tag crayfits) fits=$(first_tag fits) homarus=$(first_tag homarus) houdini=$(first_tag houdini) hypercube=$(first_tag hypercube) init=$(first_tag base) mariadb=$(first_tag mariadb11) mergepdf=$(first_tag mergepdf) solr=$(first_tag solr9)" - echo "sitectl_isle_images=" + echo "sitectl_wp_image_tags=${sitectl_wp_image_tags}" + echo "sitectl_omeka_s_image_tags=${sitectl_omeka_s_image_tags}" + echo "sitectl_omeka_classic_image_tags=${sitectl_omeka_classic_image_tags}" + echo "sitectl_ojs_image_tags=${sitectl_ojs_image_tags}" + echo "sitectl_drupal_image_tags=${sitectl_drupal_image_tags}" + echo "sitectl_isle_libops_image_tags=${sitectl_isle_libops_image_tags}" + echo "sitectl_isle_images=${sitectl_isle_images}" + echo "sitectl_create_smoke_matrix=${smoke_matrix}" } >> "$GITHUB_OUTPUT" - name: Summary @@ -134,6 +186,7 @@ jobs: echo "sitectl ojs image tags: ${{ steps.plan.outputs.sitectl_ojs_image_tags }}" echo "sitectl drupal image tags: ${{ steps.plan.outputs.sitectl_drupal_image_tags }}" echo "sitectl isle libops image tags: ${{ steps.plan.outputs.sitectl_isle_libops_image_tags }}" + echo "sitectl create smoke matrix: ${{ steps.plan.outputs.sitectl_create_smoke_matrix }}" build-level-0: if: ${{ needs.plan.outputs.level0 != '[]' }} @@ -321,49 +374,12 @@ jobs: packages: read sitectl-create-smoke-test: - if: ${{ always() && !cancelled() && !failure() }} + if: ${{ always() && needs.plan.outputs.sitectl_create_smoke_matrix != '[]' && !cancelled() && !failure() }} needs: [plan, test-level-4] strategy: fail-fast: false matrix: - include: - - plugin: wp - packages: sitectl sitectl-wp - create-args: "" - image-tags: ${{ needs.plan.outputs.sitectl_wp_image_tags }} - images: "" - - plugin: omeka-s - packages: sitectl sitectl-omeka-s - create-args: "" - image-tags: ${{ needs.plan.outputs.sitectl_omeka_s_image_tags }} - images: "" - - plugin: omeka-classic - packages: sitectl sitectl-omeka-classic - create-args: "" - image-tags: ${{ needs.plan.outputs.sitectl_omeka_classic_image_tags }} - images: "" - - plugin: ojs - packages: sitectl sitectl-ojs - create-args: "" - image-tags: ${{ needs.plan.outputs.sitectl_ojs_image_tags }} - images: "" - - plugin: drupal - packages: sitectl sitectl-drupal - create-args: "" - image-tags: ${{ needs.plan.outputs.sitectl_drupal_image_tags }} - images: "" - - plugin: isle - packages: sitectl sitectl-isle sitectl-drupal - create-args: >- - --template-repo https://github.com/libops/isle - --fcrepo off - --blazegraph off - --isle-file-system-uri private - --iiif triplet - --iiif-topology disabled - --bot-mitigation off - image-tags: ${{ needs.plan.outputs.sitectl_isle_libops_image_tags }} - images: ${{ needs.plan.outputs.sitectl_isle_images }} + include: ${{ fromJson(needs.plan.outputs.sitectl_create_smoke_matrix) }} uses: libops/.github/.github/workflows/sitectl-create-smoke-test.yaml@main with: diff --git a/images/fcrepo6/tests/SynAuthentication/test.sh b/images/fcrepo6/tests/SynAuthentication/test.sh index 2b8cce4d..191733c1 100755 --- a/images/fcrepo6/tests/SynAuthentication/test.sh +++ b/images/fcrepo6/tests/SynAuthentication/test.sh @@ -19,6 +19,19 @@ create_jwt() { printf '%s.%s' "${signing_input}" "${signature}" } +corrupt_jwt_signature() { + local header payload replacement signature token + token=${1} + IFS=. read -r header payload signature <<<"${token}" + + case "${signature:0:1}" in + A) replacement=B ;; + *) replacement=A ;; + esac + + printf '%s.%s.%s%s' "${header}" "${payload}" "${replacement}" "${signature:1}" +} + post_status() { local body_file token token=${1} @@ -42,10 +55,7 @@ if [[ "${valid_status}" != 2* ]]; then fi echo "Valid JWT accepted with HTTP ${valid_status}." -case "${valid_jwt: -1}" in -x) bad_jwt="${valid_jwt%?}y" ;; -*) bad_jwt="${valid_jwt%?}x" ;; -esac +bad_jwt=$(corrupt_jwt_signature "${valid_jwt}") bad_status=$(post_status "${bad_jwt}" /tmp/syn-bad-response.txt) if [[ "${bad_status}" != "401" ]]; then diff --git a/images/fcrepo7/tests/SynAuthentication/test.sh b/images/fcrepo7/tests/SynAuthentication/test.sh index 2b8cce4d..191733c1 100755 --- a/images/fcrepo7/tests/SynAuthentication/test.sh +++ b/images/fcrepo7/tests/SynAuthentication/test.sh @@ -19,6 +19,19 @@ create_jwt() { printf '%s.%s' "${signing_input}" "${signature}" } +corrupt_jwt_signature() { + local header payload replacement signature token + token=${1} + IFS=. read -r header payload signature <<<"${token}" + + case "${signature:0:1}" in + A) replacement=B ;; + *) replacement=A ;; + esac + + printf '%s.%s.%s%s' "${header}" "${payload}" "${replacement}" "${signature:1}" +} + post_status() { local body_file token token=${1} @@ -42,10 +55,7 @@ if [[ "${valid_status}" != 2* ]]; then fi echo "Valid JWT accepted with HTTP ${valid_status}." -case "${valid_jwt: -1}" in -x) bad_jwt="${valid_jwt%?}y" ;; -*) bad_jwt="${valid_jwt%?}x" ;; -esac +bad_jwt=$(corrupt_jwt_signature "${valid_jwt}") bad_status=$(post_status "${bad_jwt}" /tmp/syn-bad-response.txt) if [[ "${bad_status}" != "401" ]]; then diff --git a/images/ojs/rootfs/etc/confd/templates/config.inc.tmpl b/images/ojs/rootfs/etc/confd/templates/config.inc.tmpl index 3e2c62f2..04a0f01f 100644 --- a/images/ojs/rootfs/etc/confd/templates/config.inc.tmpl +++ b/images/ojs/rootfs/etc/confd/templates/config.inc.tmpl @@ -1,4 +1,5 @@ {{- define "doubleQuoteEscape" -}}{{- $escaped := replace . "\\" "\\\\" -1 -}}{{- replace $escaped "\"" "\\\"" -1 -}}{{- end -}} +{{- define "booleanOnOff" -}}{{- if or (eq . "1") (eq . "on") (eq . "On") (eq . "ON") (eq . "true") (eq . "True") (eq . "TRUE") (eq . "y") (eq . "Y") (eq . "yes") (eq . "Yes") (eq . "YES") -}}On{{- else -}}Off{{- end -}}{{- end -}} ; ; DO NOT DELETE THE ABOVE LINE!!! ; Doing so will expose this configuration file through your web site! @@ -118,7 +119,7 @@ enable_minified = On ; Provide a unique site ID and OAI base URL to PKP for statistics and security ; alert purposes only. -enable_beacon = {{ if getenv "OJS_ENABLE_BEACON" }}On{{ else }}Off{{ end }} +enable_beacon = {{ template "booleanOnOff" (getenv "OJS_ENABLE_BEACON") }} ; Set this to "On" if you would like to only have a single, site-wide Privacy ; Statement, rather than a separate Privacy Statement for each journal. Setting diff --git a/internal/buildkit/metadata_test.go b/internal/buildkit/metadata_test.go index e6a22cc3..caada06a 100644 --- a/internal/buildkit/metadata_test.go +++ b/internal/buildkit/metadata_test.go @@ -151,6 +151,22 @@ func TestMariaDBLongrunStartsServer(t *testing.T) { } } +func TestOJSEnableBeaconTemplateUsesTruthyHelper(t *testing.T) { + root := repoRoot(t) + templateFile := filepath.Join(root, "images", "ojs", "rootfs", "etc", "confd", "templates", "config.inc.tmpl") + content, err := os.ReadFile(templateFile) + if err != nil { + t.Fatal(err) + } + got := string(content) + if strings.Contains(got, `if getenv "OJS_ENABLE_BEACON"`) { + t.Fatalf("%s treats any non-empty OJS_ENABLE_BEACON value as On", templateFile) + } + if !strings.Contains(got, `define "booleanOnOff"`) || !strings.Contains(got, `enable_beacon = {{ template "booleanOnOff" (getenv "OJS_ENABLE_BEACON") }}`) { + t.Fatalf("%s must render OJS_ENABLE_BEACON through the booleanOnOff helper", templateFile) + } +} + func TestBaseVaultSecretsBootstrap(t *testing.T) { root := repoRoot(t)