Skip to content

Commit 3143ad7

Browse files
authored
ci: add gcb script to promote images on GitHub release (#111)
1 parent 70f0f74 commit 3143ad7

File tree

3 files changed

+255
-57
lines changed

3 files changed

+255
-57
lines changed

CONTRIBUTING.md

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,71 @@ again.
2626
2. Fork the repository into your own Github account.
2727
3. Please include unit tests (and integration tests if applicable) for all new code.
2828
4. Make sure all existing tests pass.
29-
* TBD
3029
5. Associate the change with an existing issue or file a [new issue](../../issues).
3130
6. Create a pull request!
31+
32+
33+
# Development
34+
35+
This project uses Skaffold's multiple config support to allow
36+
developing for each language runtime separately.
37+
38+
Each language runtime is broken out to a separate directory
39+
with a `skaffold.yaml` for development of the `duct-tape` initContainer
40+
image. Each image is expected to be standalone and should not require
41+
downloading additional content across the network. To add support for a new
42+
language runtime, an image definition should download the necessary
43+
files into the container image. The image's entrypoint should then
44+
copy those files into place at `/dbg/<runtime>`. The image should
45+
be added to the respective `skaffold.yaml` and referenced within
46+
`test/k8s-*-installation.yaml`.
47+
48+
We currently build language support images for both `linux/amd64` and
49+
`linux/arm64`.
50+
51+
Images are currently published with two names: the short-form (like
52+
`go`) and a longer-form (`skaffold-debug-go`). The short-forms are
53+
marked as deprecated as we intend to move away from, but they are
54+
still used by Skaffold.
55+
56+
## Testing
57+
58+
Integration tests are found under each language runtime directory in
59+
`test/`. These tests build and launch applications as pods that
60+
are similar to the transformed form produced by `skaffold debug`.
61+
To run:
62+
63+
```sh
64+
sh run-its.sh
65+
```
66+
67+
You can run this script from a language-runtime location too to
68+
test only that runtime's support:
69+
70+
```sh
71+
cd nodejs
72+
sh ../run-its.sh
73+
```
74+
75+
# Staging and Deploying
76+
77+
To stage a set of images for testing use the following command,
78+
where `$REPO` is the image repository where you plan to host the
79+
images.
80+
```sh
81+
skaffold build -p release,deprecated-names --default-repo $REPO
82+
```
83+
84+
The `release` profile causes the images to be pushed to the specified
85+
repository and also enables multi-arch builds using buildx (default
86+
`linux/amd64` and `linux/arm64`). The `deprecated-names` profile enables
87+
using the short-form image names (`go`, `netcore`, `nodejs`, `python`)
88+
that are currently used by `skaffold debug`.
89+
90+
Then configure Skaffold to point to that location:
91+
```sh
92+
skaffold config set --global debug-helpers-registry $REPO
93+
```
94+
95+
You should then be able to use `skaffold debug` with the
96+
staged images.

README.md

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
![experimental](https://img.shields.io/badge/stability-experimental-orange.svg)
22

3-
# Container Runtime Debugging Support (aka Duct Tape)
3+
# Container Runtime Debugging Support Images (aka Duct Tape)
44

5-
This repository gathers additional dependencies required to debug
6-
particular language runtimes with [`skaffold debug`](https://skaffold.dev/docs/how-tos/debug/).
7-
These dependencies are packaged as a set of container images suitable
8-
for use as `initContainer`s on a pod. When executed, a container image
9-
copies these dependencies to `/dbg/<runtimeId>`.
5+
This repository defines a set of container images that package
6+
the language runtime dependencies required to enable step-by-step
7+
debugging of apps with
8+
[`skaffold debug`](https://skaffold.dev/docs/how-tos/debug/).
9+
These container images are suitable for use as `initContainer`s on
10+
a pod. When executed, each container image copies these dependencies
11+
to `/dbg/<runtimeId>`.
1012

1113
The idea is that `skaffold debug` will transform k8s manifests to
1214
make available any support files required to debug specific language
1315
runtimes. For example, a Kubernetes podspec would be transformed to
1416

15-
- mount a volume on `/dbg` to hold the debugging support files
16-
- run one or more of these `initContainer`s to populate the volume
17-
- mount the volume on the applicable containers as `/dbg`
17+
- create a volume to hold the debugging support files
18+
- run one or more of these images as `initContainer`s to populate
19+
this volume, mounted as `/dbg`
20+
- mount this volume on the applicable containers as `/dbg`
21+
with suitably transformed command-line in the entrypoint and arguments
1822

1923
Current language runtimes:
24+
2025
* `go`: provides [Delve](https://github.com/go-delve/delve)
2126
* `python`: provides [`ptvsd`](https://github.com/Microsoft/ptvsd),
2227
a debug adapter that can be used for VS Code and more, for
@@ -25,50 +30,26 @@ Current language runtimes:
2530
args to the application invokation
2631
* `netcore`: provides `vsdbg` for .NET Core
2732

28-
## Development
29-
30-
This project uses Skaffold's multiple config support to allow
31-
developing for each language runtime separately.
32-
33-
Each language runtime is broken out to a separate directory
34-
with a `skaffold.yaml` for development of the `duct-tape` initContainer
35-
image. Each image is expected to be standalone and not require
36-
downloading content across the network. To add support for a new
37-
language runtime, an image definition should download the necessary
38-
files into the container image. The image's entrypoint should then
39-
copy those files into place at `/dbg/<runtime>`. The image should
40-
be added to the respective `skaffold.yaml` and referenced within
41-
`test/k8s-*-installation.yaml`.
42-
43-
# Testing
44-
45-
Integration tests are found in `test/`. These tests build and
46-
launch applications as pods that are similar to the transformed
47-
form produced by `skaffold debug`. To run:
48-
49-
```sh
50-
sh run-its.sh
51-
```
52-
53-
# Staging and Deploying
54-
55-
To stage a set of images for testing use the following command,
56-
where `$REPO` is the image repository where you plan to host the
57-
images.
58-
```sh
59-
skaffold build -p release,deprecated-names --default-repo $REPO
60-
```
61-
62-
The `release` profile causes the images to be pushed to the specified
63-
repository and also enables multi-arch builds using buildx (default
64-
linux/amd64 and linux/arm64). The `deprecated-names` profile enables
65-
using the short-form image names (`go`, `netcore`, `nodejs`, `python`)
66-
which we intend to move away from.
67-
68-
Then configure Skaffold to point to that location:
69-
```sh
70-
skaffold config set --global debug-helpers-registry $REPO
71-
```
72-
73-
You should then be able to use `skaffold debug` and use the
74-
staged images.
33+
## Distribution
34+
35+
The latest released images, which are used by `skaffold debug`, are available at:
36+
37+
gcr.io/k8s-skaffold/skaffold-debug-support
38+
39+
Images from a particular release are available at:
40+
41+
gcr.io/k8s-skaffold/skaffold-debug-support/<release>
42+
43+
Images from the latest commit to HEAD are available at our staging repository:
44+
45+
us-central1-docker.pkg.dev/k8s-skaffold/skaffold-staging/skaffold-debug-support
46+
47+
You can configure Skaffold to use a specific release or the staging
48+
repository with the following:
49+
50+
skaffold config set --global debug-helpers-registry <repository>
51+
52+
53+
# Contributing
54+
55+
See [CONTRIBUTING](CONTRIBUTING.md) for how to contribute!

hack/cloudbuild-promote.yaml

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#
2+
# Use GitHub releases to promote container-debug-support images
3+
4+
# We use GitHub release triggers to promote the images corresponding to
5+
# the release commit from staging ($_STAGING) to the production location ($_PROD).
6+
# Images are tagged with the $SHORT_SHA and $TAG_NAME where appropriate.
7+
#
8+
# Release tags ($TAG_NAME) are expected to follow a `vN.N` pattern and are
9+
# expected to be distinct. The `vN` indicates a major version (e.g., v1.35 -> v1).
10+
# These release tags are generally expected to be distinct, such that they
11+
# shouldn't be overwritten by accident.
12+
#
13+
# This promotion script copies the long- and short-form images to:
14+
#
15+
# 1. $_PROD/$TAG_NAME tagged with `latest` and `$SHORT_SHA`
16+
# Users can then use a specific release with:
17+
# ```
18+
# skaffold config set --global debug-helpers-registry $_PROD/$TAG_NAME
19+
# ```
20+
# 2. $_PROD/$MAJORVER tagged with `latest`, `$TAG_NAME`, and `$SHORT_SHA`,
21+
# when $_IS_LATEST is true and $TAG_NAME has a valid major version
22+
# 3. $_PROD for backward compatibility, tagged with `latest`, `$TAG_NAME`, and `$SHORT_NAME`,
23+
# when $_IS_LATEST is true and the major version is `v1`.
24+
#
25+
# For example, tagging commit 70f0f74 as v1.1 should result in the images being
26+
# copied over as:
27+
#
28+
# 1. gcr.io/k8s-skaffold/skaffold-debug-support/v1.1/<image>:{latest,70f0f74}
29+
# 2. gcr.io/k8s-skaffold/skaffold-debug-support/v1/<image>:{latest,v1.1,70f0f74}
30+
# 3. gcr.io/k8s-skaffold/skaffold-debug-support/<image>:{latest,v1.1,70f0f74}
31+
#
32+
# The last location (3) occurs because the major version is v1. This copy is to maintain
33+
# backwards compatibility with the existing versions of Skaffold. When we bump the
34+
# major version to v2, we will no longer copy images into (3).
35+
#
36+
# To test:
37+
# $ export CLOUDSDK_CORE_PROJECT=bdealwis-playground
38+
# $ gcloud builds submit --config=hack/cloudbuild-promote.yaml \
39+
# --substitutions=SHORT_SHA=999999,TAG_NAME=v1.23,_STAGING=us-central1-docker.pkg.dev/$CLOUDSDK_CORE_PROJECT/junk/skaffold-debug-support,_PROD=gcr.io/$CLOUDSDK_CORE_PROJECT/skaffold-debug-support
40+
#
41+
# To replace a previous release with rebuilt images:
42+
# $ gcloud builds submit --config=hack/cloudbuild-promote.yaml \
43+
# --substitutions=SHORT_SHA=xxxx,TAG_NAME=v1.23,_STAGING=us-central1-docker.pkg.dev/$CLOUDSDK_CORE_PROJECT/junk/skaffold-debug-support,_PROD=gcr.io/$CLOUDSDK_CORE_PROJECT/skaffold-debug-support,_IS_LATEST=0
44+
#
45+
options:
46+
#machineType: 'E2_HIGHCPU_8'
47+
48+
substitutions:
49+
_STAGING: us-central1-docker.pkg.dev/$PROJECT_ID/skaffold-staging/skaffold-debug-support
50+
_PROD: gcr.io/$PROJECT_ID/skaffold-debug-support
51+
_RUNTIMES: go netcore nodejs python
52+
_IS_LATEST: "1"
53+
54+
steps:
55+
###################################################################
56+
# Validate that $TAG_NAME is an acceptable image component name and tag
57+
# Regexs from https://github.com/opencontainers/distribution-spec/blob/main/spec.md
58+
- id: validate-tag
59+
name: bash
60+
entrypoint: 'bash'
61+
args:
62+
- '-eEuo'
63+
- 'pipefail'
64+
- '-c'
65+
- |-
66+
if [[ "$TAG_NAME" =~ ^[a-z0-9]+([._-][a-z0-9]+)*$ ]] \
67+
&& [[ "$TAG_NAME" =~ ^[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}$ ]]; then
68+
echo "Accepted tag"
69+
else
70+
echo "Release tag [$TAG_NAME] is not a valid image name component or image tag"
71+
exit 1
72+
fi
73+
74+
###################################################################
75+
# Copy the staged images to release loction in $_PROD/$TAG_NAME.
76+
# This allows users to use a specific release with:
77+
# skaffold config set --global debug-helpers-registry $_PROD/$TAG_NAME
78+
#
79+
# First copy staged images into $_PROD/$TAG_NAME tagged with $SHORT_SHA.
80+
# If this step fails, then nothing irrevocable has occurred.
81+
- id: install-release-images
82+
name: gcr.io/go-containerregistry/gcrane:debug
83+
entrypoint: /busybox/sh
84+
args:
85+
- "-euc"
86+
- |-
87+
for runtime in $_RUNTIMES; do
88+
gcrane copy $_STAGING/$SHORT_SHA/skaffold-debug-$$runtime:latest $_PROD/$TAG_NAME/skaffold-debug-$$runtime:$SHORT_SHA
89+
gcrane copy $_STAGING/$SHORT_SHA/$$runtime:latest $_PROD/$TAG_NAME/$$runtime:$SHORT_SHA
90+
done
91+
# Then install these images by tagging them with `latest`.
92+
- id: promote-release-images
93+
name: gcr.io/go-containerregistry/gcrane:debug
94+
entrypoint: /busybox/sh
95+
args:
96+
- "-euc"
97+
- |-
98+
for runtime in $_RUNTIMES; do
99+
gcrane tag $_PROD/$TAG_NAME/skaffold-debug-$$runtime:$SHORT_SHA latest
100+
gcrane tag $_PROD/$TAG_NAME/$$runtime:$SHORT_SHA latest
101+
done
102+
echo "Images promoted to $_PROD/$TAG_NAME"
103+
104+
# Promote to major version (e.g., v1.35 -> v1).
105+
# If IS_LATEST=1 copy these tagged images into latest.
106+
- id: promote-to-major-version
107+
name: gcr.io/go-containerregistry/gcrane:debug
108+
entrypoint: /busybox/sh
109+
args:
110+
- "-euc"
111+
- |-
112+
MAJORVER=$$(echo $TAG_NAME | sed -n 's/\(v[0-9][0-9]\)*\.[0-9.]*/\1/p')
113+
if [ -z "$$MAJORVER" ]; then
114+
echo "Skipping rest of promotion: Release tag [${TAG_NAME}] does not have [vN.*] major version"
115+
exit 0
116+
fi
117+
118+
for runtime in $_RUNTIMES; do
119+
gcrane copy $_STAGING/$SHORT_SHA/skaffold-debug-$$runtime:latest $_PROD/$$MAJORVER/skaffold-debug-$$runtime:$SHORT_SHA
120+
gcrane copy $_STAGING/$SHORT_SHA/$$runtime:latest $_PROD/$$MAJORVER/$$runtime:$SHORT_SHA
121+
if [ "$$MAJORVER" = v1 ]; then
122+
gcrane copy $_STAGING/$SHORT_SHA/skaffold-debug-$$runtime:latest $_PROD/skaffold-debug-$$runtime:$SHORT_SHA
123+
gcrane copy $_STAGING/$SHORT_SHA/$$runtime:latest $_PROD/$$runtime:$SHORT_SHA
124+
fi
125+
done
126+
for runtime in $_RUNTIMES; do
127+
gcrane tag $_PROD/$$MAJORVER/skaffold-debug-$$runtime:$SHORT_SHA $TAG_NAME
128+
gcrane tag $_PROD/$$MAJORVER/$$runtime:$SHORT_SHA $TAG_NAME
129+
if [ "$$MAJORVER" = v1 ]; then
130+
gcrane tag $_PROD/skaffold-debug-$$runtime:$SHORT_SHA $TAG_NAME
131+
gcrane tag $_PROD/$$runtime:$SHORT_SHA $TAG_NAME
132+
fi
133+
done
134+
case "$_IS_LATEST" in
135+
0|no|NO|false|FALSE) echo "skipping promotion to latest as _IS_LATEST=${_IS_LATEST}"; exit 0;;
136+
esac
137+
138+
for runtime in $_RUNTIMES; do
139+
gcrane tag $_PROD/$$MAJORVER/skaffold-debug-$$runtime:$SHORT_SHA latest
140+
gcrane tag $_PROD/$$MAJORVER/$$runtime:$SHORT_SHA latest
141+
done
142+
echo "Images promoted to $_PROD/$$MAJORVER as latest"
143+
144+
if [ "$$MAJORVER" = v1 ]; then
145+
for runtime in $_RUNTIMES; do
146+
gcrane tag $_PROD/skaffold-debug-$$runtime:$SHORT_SHA latest
147+
gcrane tag $_PROD/$$runtime:$SHORT_SHA latest
148+
done
149+
echo "Images promoted to $_PROD as latest"
150+
fi
151+
152+
timeout: 200s

0 commit comments

Comments
 (0)