-
Notifications
You must be signed in to change notification settings - Fork 127
Signing using Infra pipeline #621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f8b16c5
2f5da03
d7fd89e
c25ee62
8d83762
1638655
377542f
c1d4932
79398d8
e62f97c
813403c
734fb4f
9c7444e
e0631f5
54eabad
a43dba5
5cd4100
4c02fa3
5135f2e
2599351
25056cf
07eb67b
ec60ddb
cf966b6
057f9b7
faaa82e
7e9bf7b
8dd5fc7
1d7a5dc
c280160
24964e9
9cc2640
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,8 @@ | |
| pipeline { | ||
| agent { label 'ubuntu-18 && immutable' } | ||
| environment { | ||
| REPO = "elastic-package" | ||
|
|
||
| BASE_DIR="src/github.com/elastic/elastic-package" | ||
| JOB_GIT_CREDENTIALS = "f6c7695a-671e-4f4f-a331-acdce44ff9ba" | ||
| GITHUB_TOKEN_CREDENTIALS = "2a9602aa-ab9f-4e52-baf3-b71ca88469c7" | ||
|
|
@@ -16,6 +18,16 @@ pipeline { | |
| JOB_GCS_BUCKET = 'beats-ci-temp' | ||
| JOB_GCS_CREDENTIALS = 'beats-ci-gcs-plugin' | ||
| JOB_GCS_EXT_CREDENTIALS = 'beats-ci-gcs-plugin-file-credentials' | ||
| JOB_SIGNING_CREDENTIALS = 'sign-artifacts-with-gpg-job' | ||
| INTERNAL_CI_JOB_GCS_CREDENTIALS = 'internal-ci-gcs-plugin' | ||
|
|
||
| INFRA_SIGNING_BUCKET_NAME = 'internal-ci-artifacts' | ||
| INFRA_SIGNING_BUCKET_ARTIFACTS_SUBFOLDER = "${env.REPO}/${env.BUILD_TAG}" | ||
| INFRA_SIGNING_BUCKET_SIGNED_ARTIFACTS_SUBFOLDER = "${env.INFRA_SIGNING_BUCKET_ARTIFACTS_SUBFOLDER}/signed-artifacts" | ||
| INFRA_SIGNING_BUCKET_ARTIFACTS_PATH = "gs://${env.INFRA_SIGNING_BUCKET_NAME}/${env.INFRA_SIGNING_BUCKET_ARTIFACTS_SUBFOLDER}" | ||
| INFRA_SIGNING_BUCKET_SIGNED_ARTIFACTS_PATH = "gs://${env.INFRA_SIGNING_BUCKET_NAME}/${env.INFRA_SIGNING_BUCKET_SIGNED_ARTIFACTS_SUBFOLDER}" | ||
|
|
||
| INTEGRATIONS_SIGNATURES_PATH = 'build/integrations-elastic-signatures' // different path not to override signatures archived in the "build-zip" step | ||
| } | ||
| options { | ||
| timeout(time: 1, unit: 'HOURS') | ||
|
|
@@ -74,9 +86,7 @@ pipeline { | |
| always { | ||
| dir("${BASE_DIR}") { | ||
| archiveArtifacts(allowEmptyArchive: true, artifacts: 'build/test-results/*.xml') | ||
| junit(allowEmptyResults: false, | ||
| keepLongStdio: true, | ||
| testResults: "build/test-results/*.xml") | ||
| junit(allowEmptyResults: false, keepLongStdio: true, testResults: "build/test-results/*.xml") | ||
| stashCoverageReport() | ||
| } | ||
| } | ||
|
|
@@ -99,7 +109,8 @@ pipeline { | |
| 'check-packages-with-kind': generateTestCommandStage(command: 'test-check-packages-with-kind', artifacts: ['build/test-results/*.xml', 'build/kubectl-dump.txt', 'build/elastic-stack-dump/check-*/logs/*.log', 'build/elastic-stack-dump/check-*/logs/fleet-server-internal/*'], junitArtifacts: true, publishCoverage: true), | ||
| 'check-packages-other': generateTestCommandStage(command: 'test-check-packages-other', artifacts: ['build/test-results/*.xml', 'build/elastic-stack-dump/check-*/logs/*.log', 'build/elastic-stack-dump/check-*/logs/fleet-server-internal/*'], junitArtifacts: true, publishCoverage: true), | ||
| 'build-zip': generateTestCommandStage(command: 'test-build-zip', artifacts: ['build/elastic-stack-dump/build-zip/logs/*.log', 'build/integrations/*.sig']), | ||
| 'profiles-command': generateTestCommandStage(command: 'test-profiles-command') | ||
| 'profiles-command': generateTestCommandStage(command: 'test-profiles-command'), | ||
| 'sign-with-elastic': generateTestSignWithElasticStage() | ||
| ] | ||
|
|
||
| def checkSinglePackageTasks = generateTestCheckSinglePackageStage(artifacts: ['build/test-results/*.xml', 'build/elastic-stack-dump/check-*/logs/*.log', 'build/elastic-stack-dump/check-*/logs/fleet-server-internal/*'], junitArtifacts: true, publishCoverage: true) | ||
|
|
@@ -144,6 +155,40 @@ def cleanup(){ | |
| unstash 'source' | ||
| } | ||
|
|
||
| def generateTestSignWithElasticStage() { | ||
| return { | ||
| withNode(labels: "ubuntu-20 && immutable", sleepMax: 20, forceWorkspace: true) { | ||
| cleanup() | ||
| dir("${BASE_DIR}"){ | ||
| withMageEnv(){ | ||
| sh(label: 'Install elastic-package',script: "make install") | ||
| sh(label: 'Prepare for tests (build zipped packages)',script: "make build-unsigned-zip-for-tests") | ||
| googleStorageUpload(bucket: env.INFRA_SIGNING_BUCKET_ARTIFACTS_PATH, | ||
| credentialsId: env.INTERNAL_CI_JOB_GCS_CREDENTIALS, | ||
| pathPrefix: 'build/integrations/', | ||
| pattern: 'build/integrations/*.zip', | ||
| sharedPublicly: false, | ||
| showInline: true) | ||
| withCredentials([string(credentialsId: env.JOB_SIGNING_CREDENTIALS, variable: 'TOKEN')]) { | ||
| triggerRemoteJob(auth: CredentialsAuth(credentials: 'local-readonly-api-token'), | ||
| job: 'https://internal-ci.elastic.co/job/elastic+unified-release+master+sign-artifacts-with-gpg', | ||
| token: TOKEN, | ||
| parameters: "gcs_input_path=${env.INFRA_SIGNING_BUCKET_ARTIFACTS_PATH}", | ||
| useCrumbCache: true, | ||
| useJobInfoCache: true) | ||
| } | ||
| googleStorageDownload(bucketUri: "${env.INFRA_SIGNING_BUCKET_SIGNED_ARTIFACTS_PATH}/*", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this downloading all the packages ever signed? Or there is some cleanup process for the signed artifacts path? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be ownest with you I have never tried downloading everything in that bucket as it could kill the CI worker :D It's the same job we're using to sign Beats artifacts. |
||
| credentialsId: env.INTERNAL_CI_JOB_GCS_CREDENTIALS, | ||
| localDirectory: "${env.INTEGRATIONS_SIGNATURES_PATH}/", | ||
| pathPrefix: "${env.INFRA_SIGNING_BUCKET_SIGNED_ARTIFACTS_SUBFOLDER}") | ||
| sh(label: 'Rename .asc to .sig', script: 'for f in ' + "${env.INTEGRATIONS_SIGNATURES_PATH}" + '/*.asc; do mv "$f" "${f%.asc}.sig"; done') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be nice to encapsulate these steps of uploading, signing, downloading and renaming into a single There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, they will be encapsulated. I'm planning to wrap (signing + push to Package Storage) into a single command. I have to make sure the push works correctly. |
||
| archiveArtifacts(artifacts: "${env.INTEGRATIONS_SIGNATURES_PATH}/*.sig") | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| def generateTestCheckSinglePackageStage(Map args = [:]) { | ||
| def artifacts = args.get('artifacts') ? args.get('artifacts') : [] | ||
| def junitArtifacts = args.get('junitArtifacts') ? args.get('junitArtifacts') : false | ||
|
|
@@ -293,4 +338,4 @@ def withCloudTestEnv(Closure body) { | |
| withEnvMask(vars: maskedVars) { | ||
| body() | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -euxo pipefail | ||
|
|
||
| OLDPWD=$PWD | ||
|
|
||
| # Build packages | ||
| for d in test/packages/*/*/; do | ||
| ( | ||
| cd $d | ||
| elastic-package build --zip -v | ||
| ) | ||
| done | ||
| cd - |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, does this job check that this path belongs to elastic? In case somehow a malicious pipeline triggers this job to sign anything placed in a bucket with public access.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The job is configured in the internal-ci instance, so the malicious user should be also internal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering more about a change in the Jenkinsfile in a PR.