Skip to content

Commit 8404bc1

Browse files
Update build_multi_cluster_binary evg function to use goreleaser to build kubectl mongodb binary
1 parent cda9f73 commit 8404bc1

File tree

4 files changed

+190
-5
lines changed

4 files changed

+190
-5
lines changed

.evergreen-functions.yml

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,12 +490,53 @@ functions:
490490
- rh_pyxis
491491
binary: scripts/dev/run_python.sh scripts/preflight_images.py --image ${image_name} --submit "${preflight_submit}"
492492

493+
install_macnotary:
494+
- command: shell.exec
495+
type: setup
496+
params:
497+
include_expansions_in_env:
498+
- notary_service_url
499+
script: |
500+
set -Eeu pipefail
501+
502+
curl "${notary_service_url}" --output macos-notary.zip
503+
unzip -u macos-notary.zip
504+
chmod 755 ./linux_amd64/macnotary
505+
506+
install_goreleaser:
507+
- command: shell.exec
508+
type: setup
509+
include_expansions_in_env:
510+
- goreleaser_pro_tar_gz
511+
params:
512+
working_dir: src/github.com/mongodb/mongodb-kubernetes
513+
script: |
514+
set -Eeu pipefail
515+
curl -fL "${goreleaser_pro_tar_gz}" --output goreleaser_Linux_x86_64.tar.gz
516+
tar -xf goreleaser_Linux_x86_64.tar.gz
517+
chmod 755 ./goreleaser
518+
493519
build_multi_cluster_binary:
494520
- command: subprocess.exec
495521
type: setup
496522
params:
523+
include_expansions_in_env:
524+
- github_commit
525+
- GRS_USERNAME
526+
- GRS_PASSWORD
527+
- PKCS11_URI
528+
- ARTIFACTORY_URL
529+
- ARTIFACTORY_PASSWORD
530+
- SIGNING_IMAGE_URI
531+
- macos_notary_keyid
532+
- macos_notary_secret
533+
- workdir
534+
- triggered_by_git_tag
535+
env:
536+
MACOS_NOTARY_KEY: ${macos_notary_keyid}
537+
MACOS_NOTARY_SECRET: ${macos_notary_secret}
497538
working_dir: src/github.com/mongodb/mongodb-kubernetes
498-
binary: scripts/evergreen/build_multi_cluster_kubeconfig_creator.sh
539+
binary: scripts/dev/run_python.sh scripts/release/kubectl-mongodb/python/build_kubectl_plugin.py
499540

500541
build_and_push_appdb_database:
501542
- command: subprocess.exec

.evergreen.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ variables:
8383
- func: clone
8484
- func: download_kube_tools
8585
- func: setup_building_host
86+
- func: install_goreleaser
87+
- func: install_macnotary
8688
- func: build_multi_cluster_binary
8789

8890
- &setup_and_teardown_group_gke_code_snippets
@@ -92,6 +94,8 @@ variables:
9294
- func: setup_gcloud_cli
9395
- func: setup_mongosh
9496
- func: download_kube_tools
97+
- func: install_goreleaser
98+
- func: install_macnotary
9599
- func: build_multi_cluster_binary
96100
teardown_group:
97101
- func: upload_code_snippets_logs
@@ -394,6 +398,8 @@ tasks:
394398
commands:
395399
- func: clone
396400
- func: setup_building_host
401+
- func: install_goreleaser
402+
- func: install_macnotary
397403
- func: build_multi_cluster_binary
398404
- func: pipeline
399405
vars:

build_info.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,14 +279,14 @@
279279
"binaries": {
280280
"kubectl-mongodb": {
281281
"patch": {
282-
"s3-store": "s3://kubectl-mongodb/dev",
282+
"s3-store": "mongodb-kubernetes-dev",
283283
"platforms": [
284284
"linux/amd64"
285285
]
286286
},
287287
"staging": {
288-
"sign": true,
289-
"s3-store": "s3://kubectl-mongodb/staging",
288+
"sign": false,
289+
"s3-store": "mongodb-kubernetes-staging",
290290
"platforms": [
291291
"darwin/amd64",
292292
"darwin/arm64",
@@ -296,7 +296,7 @@
296296
},
297297
"release": {
298298
"sign": true,
299-
"s3-store": "s3://kubectl-mongodb/prod",
299+
"s3-store": "mongodb-kubernetes-release",
300300
"platforms": [
301301
"darwin/amd64",
302302
"darwin/arm64",
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import os
2+
import subprocess
3+
import sys
4+
5+
import boto3
6+
from botocore.exceptions import ClientError, NoCredentialsError, PartialCredentialsError
7+
8+
from lib.base_logger import logger
9+
from scripts.release.build.build_info import (
10+
load_build_info,
11+
)
12+
from scripts.release.build.build_scenario import (
13+
BuildScenario,
14+
)
15+
16+
AWS_REGION = "eu-north-1"
17+
KUBECTL_PLUGIN_BINARY_NAME = "kubectl-mongodb"
18+
S3_BUCKET_KUBECTL_PLUGIN_SUBPATH = KUBECTL_PLUGIN_BINARY_NAME
19+
20+
GORELEASER_DIST_DIR = "dist"
21+
22+
# LOCAL_KUBECTL_PLUGIN_PATH the full filename where tests image expects the kuebctl-mongodb binary to be available
23+
LOCAL_KUBECTL_PLUGIN_PATH = "docker/mongodb-kubernetes-tests/multi-cluster-kube-config-creator_linux"
24+
25+
26+
def run_goreleaser():
27+
try:
28+
command = ["./goreleaser", "build", "--snapshot", "--clean", "--skip", "post-hooks"]
29+
30+
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1)
31+
32+
for log in iter(process.stdout.readline, ""):
33+
print(log, end="")
34+
35+
process.stdout.close()
36+
exit_code = process.wait()
37+
38+
if exit_code != 0:
39+
logger.debug(f"GoReleaser command failed with exit code {exit_code}.")
40+
sys.exit(1)
41+
42+
logger.info("GoReleaser build completed successfully!")
43+
44+
except FileNotFoundError:
45+
logger.debug(
46+
"ERROR: 'goreleaser' command not found. Please ensure goreleaser is installed and in your system's PATH."
47+
)
48+
sys.exit(1)
49+
except Exception as e:
50+
logger.debug(f"An unexpected error occurred while running `goreleaser build`: {e}")
51+
sys.exit(1)
52+
53+
54+
# upload_artifacts_to_s3 uploads the artifacts that are generated by goreleaser to S3 bucket at a specific path.
55+
# The S3 bucket and version are figured out and passed to this function based on BuildScenario.
56+
def upload_artifacts_to_s3(s3_bucket: str, version: str):
57+
if not os.path.isdir(GORELEASER_DIST_DIR):
58+
logger.info(f"ERROR: GoReleaser dist directory '{GORELEASER_DIST_DIR}' not found.")
59+
sys.exit(1)
60+
61+
try:
62+
s3_client = boto3.client("s3", region_name=AWS_REGION)
63+
except (NoCredentialsError, PartialCredentialsError):
64+
logger.debug("ERROR: Failed to create S3 client. AWS credentials not found.")
65+
sys.exit(1)
66+
except Exception as e:
67+
logger.debug(f"An error occurred connecting to S3: {e}")
68+
sys.exit(1)
69+
70+
uploaded_files = 0
71+
# iterate over all the files generated by goreleaser in the dist directory and upload them to S3
72+
for root, _, files in os.walk(GORELEASER_DIST_DIR):
73+
for filename in files:
74+
local_path = os.path.join(root, filename)
75+
s3_key = s3_path(local_path, version)
76+
77+
logger.info(f"Uploading artifact {local_path} to s3://{s3_bucket}/{s3_key}")
78+
try:
79+
s3_client.upload_file(local_path, s3_bucket, s3_key)
80+
logger.info(f"Successfully uploaded the artifact {filename}")
81+
uploaded_files += 1
82+
except Exception as e:
83+
logger.debug(f"ERROR: Failed to upload file {filename}: {e}")
84+
85+
if uploaded_files > 0:
86+
logger.info(f"Successfully uploaded {uploaded_files} kubectl-mongodb plugin artifacts to S3.")
87+
88+
89+
# s3_path returns the path where the artifacts should be uploaded to in S3 object store.
90+
# For dev workflows it's going to be `kubectl-mongodb/{evg-patch-id}/{goreleaser-artifact}`,
91+
# for staging workflows it would be `kubectl-mongodb/{commit-sha}/{goreleaser-artifact}`.
92+
# The `version` string has the correct version (either patch id or commit sha), based on the BuildScenario.
93+
def s3_path(local_path: str, version: str):
94+
return f"{S3_BUCKET_KUBECTL_PLUGIN_SUBPATH}/{version}/{local_path}"
95+
96+
97+
# download_plugin_for_tests_image downloads just the linux amd64 version of the binary and places it
98+
# at the location LOCAL_KUBECTL_PLUGIN_PATH.
99+
def download_plugin_for_tests_image(build_scenario: BuildScenario, s3_bucket: str, version: str):
100+
try:
101+
s3_client = boto3.client("s3", region_name=AWS_REGION)
102+
except Exception as e:
103+
logger.debug(f"An error occurred connecting to S3 to download kubectl plugin for tests image: {e}")
104+
return
105+
106+
plugin_path = f"{S3_BUCKET_KUBECTL_PLUGIN_SUBPATH}/{version}/dist/kubectl-mongodb_linux_amd64_v1/kubectl-mongodb"
107+
108+
logger.info(f"Downloading s3://{s3_bucket}/{plugin_path} to {LOCAL_KUBECTL_PLUGIN_PATH}")
109+
try:
110+
s3_client.download_file(s3_bucket, plugin_path, LOCAL_KUBECTL_PLUGIN_PATH)
111+
# change the file's permissions to make file executable
112+
os.chmod(LOCAL_KUBECTL_PLUGIN_PATH, 0o755)
113+
114+
logger.info(f"Successfully downloaded artifact to {LOCAL_KUBECTL_PLUGIN_PATH}")
115+
except ClientError as e:
116+
if e.response["Error"]["Code"] == "404":
117+
logger.debug(f"ERROR: Artifact not found at s3://{s3_bucket}/{plugin_path} ")
118+
else:
119+
logger.debug(f"ERROR: Failed to download artifact. S3 Client Error: {e}")
120+
except Exception as e:
121+
logger.debug(f"An unexpected error occurred during download: {e}")
122+
123+
124+
def main():
125+
build_scenario = BuildScenario.infer_scenario_from_environment()
126+
kubectl_plugin_build_info = load_build_info(build_scenario).binaries[KUBECTL_PLUGIN_BINARY_NAME]
127+
128+
run_goreleaser()
129+
130+
upload_artifacts_to_s3(kubectl_plugin_build_info.s3_store, kubectl_plugin_build_info.version)
131+
132+
download_plugin_for_tests_image(
133+
build_scenario, kubectl_plugin_build_info.s3_store, kubectl_plugin_build_info.version
134+
)
135+
136+
137+
if __name__ == "__main__":
138+
main()

0 commit comments

Comments
 (0)