From 9ee1bb82ac7c06ffc0df75fcf9fbe95f0edf8b69 Mon Sep 17 00:00:00 2001 From: David Galloway Date: Thu, 11 Jun 2026 16:27:10 -0400 Subject: [PATCH 1/6] cve-pipeline: Creation This enables us to build packages and containers from ceph-private.git privately. This includes Jenkins build logs, artifacts, packages, and containers. Packages will be pushed to the internal-only pulp instance and containers to the internal-only quay instance. To avoid job duplication, each job pulls in the respective Jenkinsfiles e.g., - cve-pipelinen -> ceph-dev-pipeline - cve-source-dist -> ceph-source-dist The only difference is the parameters we pass to the job. The key differences there are CEPH_REPO points to ceph-private.git whereas ceph-dev-pipeline is not capable of doing so. We also tell the pipeline not to use a public chacra instance. Signed-off-by: David Galloway --- ceph-dev-pipeline/build/Jenkinsfile | 5 +- .../config/definitions/cve-pipeline.yml | 128 ++++++++++++++++++ .../config/definitions/cve-source-dist.yml | 78 +++++++++++ 3 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 cve-pipeline/config/definitions/cve-pipeline.yml create mode 100644 cve-source-dist/config/definitions/cve-source-dist.yml diff --git a/ceph-dev-pipeline/build/Jenkinsfile b/ceph-dev-pipeline/build/Jenkinsfile index 5265f37d4..1e7fb10f9 100644 --- a/ceph-dev-pipeline/build/Jenkinsfile +++ b/ceph-dev-pipeline/build/Jenkinsfile @@ -360,7 +360,8 @@ pipeline { } stage("builder container") { environment { - CONTAINER_REPO_CREDS = credentials('quay-ceph-io-ceph-ci') + // Use quay-int.front cred if cve-pipeline, otherewise default to quay.ceph.io cred + CONTAINER_REPO_CREDS = credentials("${env.JOB_NAME == 'cve-pipeline' ? 'quay-int-login' : 'quay-ceph-io-ceph-ci'}") DOCKER_HUB_CREDS = credentials('dgalloway-docker-hub') } when { @@ -631,7 +632,7 @@ pipeline { expression { env.CI_CONTAINER == 'true' && container_distros.contains(env.DIST) } } environment { - CONTAINER_REPO_CREDS = credentials('quay-ceph-io-ceph-ci') + CONTAINER_REPO_CREDS = credentials("${env.JOB_NAME == 'cve-pipeline' ? 'quay-int-login' : 'quay-ceph-io-ceph-ci'}") } steps { script { diff --git a/cve-pipeline/config/definitions/cve-pipeline.yml b/cve-pipeline/config/definitions/cve-pipeline.yml new file mode 100644 index 000000000..6f0491523 --- /dev/null +++ b/cve-pipeline/config/definitions/cve-pipeline.yml @@ -0,0 +1,128 @@ +- job: + name: cve-pipeline + properties: + - authorization: + inheritance-strategy: none + GROUP:ceph*security: + - job-read + - job-discover + - job-build + - job-cancel + - job-configure + - job-workspace + - run-replay + - run-update + - run-delete + - scm-tag + description: | + This Jenkins pipeline is only used to develop CVE fixes. Its differences are: + - The job itself is not public-facing. It does not inherit the RBAC under https://jenkins.ceph.com/manage/configureSecurity/ + - ceph-dev-pipeline pushes to the internal/private pulp instance instead of a public chacra instance + project-type: pipeline + quiet-period: 1 + concurrent: true + pipeline-scm: + scm: + - git: + url: https://github.com/ceph/ceph-build + branches: + - ${{CEPH_BUILD_BRANCH}} + shallow-clone: true + submodule: + disable: true + wipe-workspace: true + script-path: ceph-dev-pipeline/build/Jenkinsfile + lightweight-checkout: true + do-not-fetch-tags: true + + parameters: + - string: + name: BRANCH + description: "The branch from ceph-private.git to build" + default: main + + - choice: + name: SHA1 + description: "Intentionally blank. ceph-dev-pipeline requires this" + choices: + - '' + + - choice: + name: CEPH_REPO + choices: + - git@github.com:ceph/ceph-private.git + + - string: + name: DISTROS + description: "A list of distros to build for. Available options are: centos9, noble, jammy, bookworm, trixie" + default: "noble centos9 bookworm trixie" + + - string: + name: ARCHS + description: "A list of architectures to build for. Available options are: x86_64, and arm64" + default: "x86_64 arm64" + + - bool: + name: CI_COMPILE + description: "Whether to compile and build packages" + default: true + + - bool: + name: THROWAWAY + description: "DO NOT UNCHECK. This will push to a chacra node publicly!" + default: true + + - bool: + name: PULP_UPLOAD + description: "If you want packages, this must be true. We do not push to chacra for CVE builds." + default: true + + - choice: + name: FLAVORS + choices: + - default + + - bool: + name: CI_CONTAINER + description: "Whether to build and push container images" + default: true + + - string: + name: CONTAINER_REPO_HOSTNAME + description: "FQDN of container repo server (e.g. 'quay.io')" + default: "quay-int.front.sepia.ceph.com" + + - string: + name: CONTAINER_REPO_ORGANIZATION + description: "Name of container repo organization (e.g. 'ceph-ci')" + default: "ceph-ci" + + - bool: + name: DWZ + description: "Use dwz to make debuginfo packages smaller" + default: false + + - bool: + name: SCCACHE + description: "Use sccache to speed up compilation" + default: true + + - string: + name: SETUP_BUILD_ID + description: "Reuse the source distribution from this cve-source-dist build instead of creating a new one" + default: "" + + - choice: + name: SETUP_JOB + choices: + - cve-source-dist + + - string: + name: CEPH_BUILD_BRANCH + description: "Use the Jenkinsfile from this ceph-build branch" + default: main + + wrappers: + - build-name: + name: "#${{BUILD_NUMBER}} ${{BRANCH}}, ${{VERSION}}" + diff --git a/cve-source-dist/config/definitions/cve-source-dist.yml b/cve-source-dist/config/definitions/cve-source-dist.yml new file mode 100644 index 000000000..3e96d85d7 --- /dev/null +++ b/cve-source-dist/config/definitions/cve-source-dist.yml @@ -0,0 +1,78 @@ +- job: + name: cve-source-dist + description: This job is only called from https://jenkins.ceph.com/job/cve-pipeline. The entire job and its artifacts are only visible to the ceph/security Github Team. + project-type: pipeline + concurrent: true + pipeline-scm: + scm: + - git: + url: https://github.com/ceph/ceph-build + branches: + - ${{CEPH_BUILD_BRANCH}} + shallow-clone: true + submodule: + disable: true + wipe-workspace: true + script-path: ceph-source-dist/build/Jenkinsfile + lightweight-checkout: true + do-not-fetch-tags: true + properties: + - build-discarder: + days-to-keep: -1 + num-to-keep: 100 + artifact-days-to-keep: -1 + artifact-num-to-keep: 50 + - copyartifact: + projects: cve-pipeline + - authorization: + inheritance-strategy: none + GROUP:ceph*security: + - job-read + - job-discover + - job-build + - job-cancel + - job-configure + - job-workspace + - run-replay + - run-update + - run-delete + - scm-tag + + parameters: + - choice: + name: CEPH_REPO + choices: + - git@github.com:ceph/ceph-private.git + + - string: + name: BRANCH + description: "The Ceph branch to build" + + - string: + name: SHA1 + description: "The specific commit to build" + + - string: + name: CEPH_BUILD_BRANCH + description: "Use the Jenkinsfile from this ceph-build branch" + default: main + + scm: + - git: + url: ${{CEPH_REPO}} + # Use the SSH key attached to the ceph-jenkins GitHub account. + credentials-id: "jenkins-build" + branches: + - $BRANCH + timeout: 20 + skip-tag: true + wipe-workspace: true + + wrappers: + - inject-passwords: + global: true + mask-password-params: true + - credentials-binding: + - text: + credential-id: shaman-api-key + variable: SHAMAN_API_KEY From 329da2b30d5656632346459687e98119351e8a2c Mon Sep 17 00:00:00 2001 From: David Galloway Date: Fri, 12 Jun 2026 14:11:26 -0400 Subject: [PATCH 2/6] ceph-dev-pipeline: Add CHACRA_URL parameter This logic was chosen to preserve logic the THROWAWAY parameter provides regardless of package repository repository choice. Signed-off-by: David Galloway --- ceph-dev-pipeline/build/Jenkinsfile | 2 +- .../config/definitions/ceph-dev-pipeline.yml | 7 ++++++- cve-pipeline/config/definitions/cve-pipeline.yml | 9 +++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ceph-dev-pipeline/build/Jenkinsfile b/ceph-dev-pipeline/build/Jenkinsfile index 1e7fb10f9..d71703bd1 100644 --- a/ceph-dev-pipeline/build/Jenkinsfile +++ b/ceph-dev-pipeline/build/Jenkinsfile @@ -592,7 +592,7 @@ pipeline { export OS_VERSION="${os.version}" export OS_VERSION_NAME="${os.version_name}" export OS_PKG_TYPE="${os.pkg_type}" - if [ "$THROWAWAY" != "true" ]; then ./scripts/chacra_upload.sh; fi + if [ "$THROWAWAY" != "true" ] && [ "$CHACRA_UPLOAD" == "true" ]; then ./scripts/chacra_upload.sh; fi """ sh """#!/bin/bash diff --git a/ceph-dev-pipeline/config/definitions/ceph-dev-pipeline.yml b/ceph-dev-pipeline/config/definitions/ceph-dev-pipeline.yml index 0bd6ac546..59e4b8f6f 100644 --- a/ceph-dev-pipeline/config/definitions/ceph-dev-pipeline.yml +++ b/ceph-dev-pipeline/config/definitions/ceph-dev-pipeline.yml @@ -56,7 +56,7 @@ - bool: name: THROWAWAY - description: "Whether to push any binaries to Chacra" + description: "Whether to push any binaries to Chacra or Pulp. Overrides CHACRA_UPLOAD and PULP_UPLOAD if either are true." default: false - bool: @@ -64,6 +64,11 @@ description: "Whether to push new binaries to Chacra if some are already present" default: false + - bool: + name: CHACRA_UPLOAD + description: "Whether to upload packages to Chacra" + default: true + - bool: name: PULP_UPLOAD description: "Whether to upload packages to Pulp" diff --git a/cve-pipeline/config/definitions/cve-pipeline.yml b/cve-pipeline/config/definitions/cve-pipeline.yml index 6f0491523..2ad5cd029 100644 --- a/cve-pipeline/config/definitions/cve-pipeline.yml +++ b/cve-pipeline/config/definitions/cve-pipeline.yml @@ -69,8 +69,13 @@ - bool: name: THROWAWAY - description: "DO NOT UNCHECK. This will push to a chacra node publicly!" - default: true + description: "Whether to push any binaries to Chacra or Pulp. Overrides CHACRA_UPLOAD and PULP_UPLOAD if either are true." + default: false + + - bool: + name: CHACRA_UPLOAD + description: "DO NOT CHECK" + default: false - bool: name: PULP_UPLOAD From 66ce43e9e6a1d710e081e0b12a61bce95d1af3c7 Mon Sep 17 00:00:00 2001 From: David Galloway Date: Fri, 12 Jun 2026 16:56:32 -0400 Subject: [PATCH 3/6] pulp_upload.sh: Do not overwrite BRANCH name Signed-off-by: David Galloway --- scripts/pulp_upload.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/pulp_upload.sh b/scripts/pulp_upload.sh index 7ef8884cf..a7afcfbe8 100755 --- a/scripts/pulp_upload.sh +++ b/scripts/pulp_upload.sh @@ -240,7 +240,6 @@ publish_pulp_distribution() { log "Uploading artifacts to Pulp repository ..." -BRANCH=$(release_from_version "${CEPH_VERSION}") _OS_VERSION=$(resolve_os_version_for_repo) REPO_NAME="${PULP_PROJECT}-${BRANCH}-${OS_NAME}-${_OS_VERSION}" From f9bf3309ccc38b72fb94dc4c58a4b2afc425f14b Mon Sep 17 00:00:00 2001 From: David Galloway Date: Tue, 16 Jun 2026 16:22:59 -0400 Subject: [PATCH 4/6] pulp_upload.sh: Create repository before upload Signed-off-by: David Galloway --- scripts/pulp_upload.sh | 78 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/scripts/pulp_upload.sh b/scripts/pulp_upload.sh index a7afcfbe8..ea4998c43 100755 --- a/scripts/pulp_upload.sh +++ b/scripts/pulp_upload.sh @@ -9,7 +9,8 @@ # Required environment variables: # WORKSPACE - Jenkins workspace root containing dist/ceph artifacts -# CEPH_VERSION - Full Ceph version string (used to derive release branch) +# BRANCH - Ceph branch/ref name for this build (used in repository +# names and distribution base paths) # SHA1 - Git commit SHA for this build # OS_NAME - Target OS (e.g. centos, ubuntu) # OS_VERSION - Target OS version @@ -69,6 +70,41 @@ resolve_deb_upload_dir() { printf '%s\n' "${deb_tree}" } +# Ensure a Pulp repository exists, creating it if necessary. +# Repository creation is idempotent and tolerant of concurrent creation by +# other matrix arches that share repositories (e.g. noarch and source RPMs). +# Arguments: +# $1 - Pulp content type ("rpm" or "deb") +# $2 - Pulp repository name +# Returns 0 when the repository exists (or was created), 1 otherwise. +ensure_pulp_repository() { + local content_type="$1" + local repo_name="$2" + + if pulp "${content_type}" repository show --name "${repo_name}" \ + >/dev/null 2>&1; then + log "Repository ${repo_name} already exists" + return 0 + fi + + log "Creating ${content_type} repository ${repo_name}" + if pulp "${content_type}" repository create --name "${repo_name}"; then + return 0 + fi + + # A concurrent job (e.g. another arch in the same matrix uploading shared + # noarch/source packages) may have created it first; tolerate that as long + # as the repository now exists. + if pulp "${content_type}" repository show --name "${repo_name}" \ + >/dev/null 2>&1; then + log "Repository ${repo_name} created concurrently; continuing" + return 0 + fi + + log "ERROR: Failed to create ${content_type} repository ${repo_name}" + return 1 +} + # Attach previously uploaded package content to a Pulp repository. # Arguments: # $1 - Pulp content type ("rpm" or "deb") @@ -106,18 +142,31 @@ upload_rpm_to_pulp() { local repo_name="$2" local out_array_name="$3" local -n pulp_uuid="$out_array_name" + local -a rpm_files=() pulp_uuid=() log "Discovering RPM artifacts under ${rpmbuild_dir}" + if [ ! -d "${rpmbuild_dir}" ]; then + log "Directory ${rpmbuild_dir} does not exist; nothing to upload" + return 1 + fi while IFS= read -r rpm_file; do [ -z "$rpm_file" ] && continue + rpm_files+=("$rpm_file") + done < <( + find "${rpmbuild_dir}" -regextype egrep -regex ".*(\.rpm)$" + ) + if [[ ${#rpm_files[@]} -eq 0 ]]; then + log "No RPM artifacts found under ${rpmbuild_dir}" + return 1 + fi + ensure_pulp_repository rpm "${repo_name}" || return 1 + for rpm_file in "${rpm_files[@]}"; do pulp_uuid+=($(pulp rpm content -t package upload \ --repository "$repo_name" --file "$rpm_file" --no-publish | \ jq -r '.prn | split(":") | last' )) - done < <( - find "${rpmbuild_dir}" -regextype egrep -regex ".*(\.rpm)$" - ) + done log "Finished RPM uploads (repository=${repo_name})" [[ ${#pulp_uuid[@]} -gt 0 ]] } @@ -137,6 +186,7 @@ upload_deb_to_pulp() { local out_array_name="$4" local -n pulp_uuid="$out_array_name" local _arch="$arch" + local -a deb_files=() if [ "$arch" == "x86_64" ]; then _arch="amd64" @@ -146,17 +196,29 @@ upload_deb_to_pulp() { pulp_uuid=() log "Discovering .deb packages (${_arch} and all) under ${deb_dir}/" + if [ ! -d "${deb_dir}" ]; then + log "Directory ${deb_dir} does not exist; nothing to upload" + return 1 + fi while IFS= read -r deb_file; do [ -z "$deb_file" ] && continue - pulp_uuid+=($(pulp deb content -t package upload \ - --repository "$repo_name" --file "$deb_file" | \ - jq -r '.prn | split(":") | last' - )) + deb_files+=("$deb_file") done < <( find "${deb_dir}/" -regextype egrep \ -regex ".*(${_arch}|all)\.deb$" | awk -F/ '{name = $NF; if (!seen[name]++) print $0}' ) + if [[ ${#deb_files[@]} -eq 0 ]]; then + log "No .deb packages found under ${deb_dir}/" + return 1 + fi + ensure_pulp_repository deb "${repo_name}" || return 1 + for deb_file in "${deb_files[@]}"; do + pulp_uuid+=($(pulp deb content -t package upload \ + --repository "$repo_name" --file "$deb_file" | \ + jq -r '.prn | split(":") | last' + )) + done log "Finished DEB uploads (repository=${repo_name}, count=${#pulp_uuid[@]})" [[ ${#pulp_uuid[@]} -gt 0 ]] } From 045d140e7cc55c72739aef8c6fbf3af18d7ac860 Mon Sep 17 00:00:00 2001 From: David Galloway Date: Fri, 12 Jun 2026 14:20:23 -0400 Subject: [PATCH 5/6] ceph-dev-pipeline: Notify shaman of pulp repo URLs Unsure if anything even uses chacra_url. Containerfile uses `jq -r .[0].url`. Signed-off-by: David Galloway --- ceph-dev-pipeline/build/Jenkinsfile | 1 + scripts/notify_shaman_pulp_repo.sh | 65 +++++++++++++++++++++++++++++ scripts/pulp_upload.sh | 6 +++ 3 files changed, 72 insertions(+) create mode 100755 scripts/notify_shaman_pulp_repo.sh diff --git a/ceph-dev-pipeline/build/Jenkinsfile b/ceph-dev-pipeline/build/Jenkinsfile index d71703bd1..b5ed14d57 100644 --- a/ceph-dev-pipeline/build/Jenkinsfile +++ b/ceph-dev-pipeline/build/Jenkinsfile @@ -606,6 +606,7 @@ pipeline { export FLAVOR="${env.FLAVOR}" ./scripts/pulp_upload.sh + ./scripts/notify_shaman_pulp_repo.sh ready ceph ${os.name} ${os.version_name} $ARCH https://pulp.front.sepia.ceph.com/pulp/content/repos/ceph/${env.BRANCH}/${env.SHA1}/${os.name}/${os.version_name}/flavors/${env.FLAVOR}/ else echo "Skipping pulp upload because PULP_UPLOAD=$PULP_UPLOAD" fi diff --git a/scripts/notify_shaman_pulp_repo.sh b/scripts/notify_shaman_pulp_repo.sh new file mode 100755 index 000000000..4c567dd81 --- /dev/null +++ b/scripts/notify_shaman_pulp_repo.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# vim: ts=4 sw=4 expandtab + +submit_repo_status() { + + # A helper script to post (create) the status of a repo in shaman. + # 'state' is the repo status (e.g. 'ready'). + # 'project' is used to post to the right url in shaman. + # shaman keys repos by 'chacra_url' and builds Arch rows from the 'archs' + # list, so the arch must be sent as a JSON array (not 'distro_arch'). + http_method=$1 + state=$2 + project=$3 + distro=$4 + distro_version=$5 + arch=$6 + url=$7 + + # RPM builds also ship source RPMs (the SRPMS/ subdir), so advertise a + # "source" arch to shaman alongside the binary arch, mirroring chacra. + # Binary debs have no corresponding source repo. OS_PKG_TYPE is exported + # by the calling Jenkins step. + archs="\"$arch\"" + if [ "$OS_PKG_TYPE" = "rpm" ]; then + archs="${archs},\"source\"" + fi + + # package_manager_version is computed by pulp_upload.sh (a separate + # process) and handed off via this file in the shared workspace. + PACKAGE_MANAGER_VERSION="" + if [ -r "$WORKSPACE/pulp_repo_info" ]; then + source "$WORKSPACE/pulp_repo_info" + fi + + cat > $WORKSPACE/repo_status.json << EOF +{ + "url":"$url", + "chacra_url":"$url", + "status":"$state", + "distro":"$distro", + "distro_version":"$distro_version", + "archs":[$archs], + "ref":"$BRANCH", + "sha1":"$SHA1", + "flavor":"$FLAVOR", + "extra":{ + "version":"$CEPH_VERSION", + "package_manager_version":"$PACKAGE_MANAGER_VERSION", + "build_url":"$BUILD_URL", + "root_build_cause":"$ROOT_BUILD_CAUSE", + "node_name":"$NODE_NAME", + "job_name":"$JOB_NAME" + } +} +EOF + + SHAMAN_URL="https://shaman.ceph.com/api/repos/$project/" + # post the repo information as JSON to shaman + curl -X $http_method -H "Content-Type:application/json" --data "@$WORKSPACE/repo_status.json" -u $SHAMAN_API_USER:$SHAMAN_API_KEY ${SHAMAN_URL} +} + +# If the script is executed (as opposed to sourced), run the function now +if [ "$(basename -- "${0#-}")" = "$(basename -- "${BASH_SOURCE}")" ]; then + submit_repo_status "POST" "$@" +fi diff --git a/scripts/pulp_upload.sh b/scripts/pulp_upload.sh index ea4998c43..28aa94e09 100755 --- a/scripts/pulp_upload.sh +++ b/scripts/pulp_upload.sh @@ -417,3 +417,9 @@ else log "ERROR: Unsupported OS_PKG_TYPE='${OS_PKG_TYPE}' (expected rpm or deb)" exit 1 fi + +# Hand off the computed package-manager version to the shaman notify step, +# which runs as a separate process and includes it in the repo's extra +# metadata. See notify_shaman_pulp_repo.sh. +printf 'PACKAGE_MANAGER_VERSION=%q\n' "${PACKAGE_MANAGER_VERSION}" \ + > "${WORKSPACE}/pulp_repo_info" From 49b24303af5f0db6518f8d424226666d57d92292 Mon Sep 17 00:00:00 2001 From: David Galloway Date: Wed, 17 Jun 2026 09:12:13 -0400 Subject: [PATCH 6/6] ceph-dev-pipeline: Pulp repo support in ceph-release RPM's ceph.repo Signed-off-by: David Galloway --- ceph-dev-pipeline/build/Jenkinsfile | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/ceph-dev-pipeline/build/Jenkinsfile b/ceph-dev-pipeline/build/Jenkinsfile index b5ed14d57..21d30bc97 100644 --- a/ceph-dev-pipeline/build/Jenkinsfile +++ b/ceph-dev-pipeline/build/Jenkinsfile @@ -567,12 +567,25 @@ pipeline { """ // Push packages to chacra.ceph.com under the 'test' ref if ceph-release-pipeline's TEST=true env.SHA1 = env.TEST?.toBoolean() ? 'test' : env.SHA1 - def spec_text = get_ceph_release_spec_text("${chacra_url}r/ceph/${env.BRANCH}/${env.SHA1}/${os.name}/${os.version_name}/flavors/${env.FLAVOR}/") + // The ceph-release RPM ships /etc/yum.repos.d/ceph.repo, so its + // baseurls must match where packages were actually published: + // pulp when PULP_UPLOAD=true, otherwise chacra. + def spec_project_url + def repo_base_url + if ( env.PULP_UPLOAD == "true" ) { + def pulp_repo_base = "https://pulp.front.sepia.ceph.com/pulp/content/repos/ceph/${env.BRANCH}/${env.SHA1}/${os.name}/${os.version_name}/flavors/${env.FLAVOR}" + spec_project_url = "${pulp_repo_base}/" + repo_base_url = pulp_repo_base + } else { + spec_project_url = "${chacra_url}r/ceph/${env.BRANCH}/${env.SHA1}/${os.name}/${os.version_name}/flavors/${env.FLAVOR}/" + repo_base_url = "${chacra_url}/r/ceph/${env.BRANCH}/${env.SHA1}/${os.name}/${os.version_name}/flavors/${env.FLAVOR}" + } + def spec_text = get_ceph_release_spec_text(spec_project_url) writeFile( file: "dist/ceph/rpmbuild/SPECS/ceph-release.spec", text: spec_text, ) - def repo_text = get_ceph_release_repo_text("${chacra_url}/r/ceph/${env.BRANCH}/${env.SHA1}/${os.name}/${os.version_name}/flavors/${env.FLAVOR}") + def repo_text = get_ceph_release_repo_text(repo_base_url) writeFile( file: "dist/ceph/rpmbuild/SOURCES/ceph.repo", text: repo_text,