Reinstate utils image with clusterctl also installed
This commit is contained in:
parent
1d7503034c
commit
f46e1fa09f
88
.github/workflows/publish-artifacts.yaml
vendored
Normal file
88
.github/workflows/publish-artifacts.yaml
vendored
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
name: Publish artifacts
|
||||||
|
# Run the tasks on every push
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build_push_utils_image:
|
||||||
|
name: Build and push utils image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out the repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
with:
|
||||||
|
platforms: all
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Set up Docker layer caching
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: ${{ runner.os }}-buildx-api-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-buildx-api-
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Calculate metadata for image
|
||||||
|
id: image-meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: ghcr.io/stackhpc/k8s-utils
|
||||||
|
# Produce the branch name or tag and the SHA as tags
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=tag
|
||||||
|
type=sha,prefix=
|
||||||
|
|
||||||
|
- name: Build and push image
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./utils
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.image-meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.image-meta.outputs.labels }}
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||||
|
|
||||||
|
# Temp fix
|
||||||
|
# https://github.com/docker/build-push-action/issues/252
|
||||||
|
# https://github.com/moby/buildkit/issues/1896
|
||||||
|
# https://github.com/docker/buildx/pull/535
|
||||||
|
- name: Move cache
|
||||||
|
run: |
|
||||||
|
rm -rf /tmp/.buildx-cache
|
||||||
|
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||||
|
|
||||||
|
publish_charts:
|
||||||
|
name: Publish Helm charts to GitHub pages
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# We need the image to have been built (if required) and tagged before publishing charts
|
||||||
|
needs: build_push_utils_image
|
||||||
|
steps:
|
||||||
|
- name: Check out the repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
# This is important for "git rev-list --count" to work correctly when
|
||||||
|
# determining the number of commits since the last tag
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# Use an up-to-date version of Python for the script
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: 3.9
|
||||||
|
|
||||||
|
# This action packages and pushes the chart
|
||||||
|
- name: Publish charts
|
||||||
|
run: ./scripts/publish-charts.py
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
25
.github/workflows/publish-helm-charts.yaml
vendored
25
.github/workflows/publish-helm-charts.yaml
vendored
@ -1,25 +0,0 @@
|
|||||||
name: Publish Helm charts
|
|
||||||
# Run the tasks on every push
|
|
||||||
on: push
|
|
||||||
jobs:
|
|
||||||
publish_charts:
|
|
||||||
name: Publish Helm charts to GitHub pages
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out the repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
# This is important for "git rev-list --count" to work correctly when
|
|
||||||
# determining the number of commits since the last tag
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
# Use an up-to-date version of Python for the script
|
|
||||||
- uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: 3.9
|
|
||||||
|
|
||||||
# This action packages and pushes the chart
|
|
||||||
- name: Publish charts
|
|
||||||
run: ./scripts/publish-charts.py
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -60,12 +60,16 @@ SEMVER_REGEX = r"^v?(?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<patch>[0-9]+)(-(?P<p
|
|||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
"""
|
"""
|
||||||
Returns a (version, is_tag) tuple where version is a SemVer-compliant version based on Git information
|
Returns a (version, app_version, is_tag) tuple where version is a SemVer-compliant version based on
|
||||||
for the current working directory and is_tag is true iff the current commit is a tagged commit.
|
Git information for the current working directory, app_version is the short-sha as used to tag the
|
||||||
|
utils image and is_tag is true iff the current commit is a tagged commit.
|
||||||
|
|
||||||
The version is based on the distance from the last tag and includes the name of the branch that the
|
The version is based on the distance from the last tag and includes the name of the branch that the
|
||||||
commit is on. It is is constructed such that the versions for a particular branch will order correctly.
|
commit is on. It is is constructed such that the versions for a particular branch will order correctly.
|
||||||
"""
|
"""
|
||||||
|
# The app version is always the short SHA
|
||||||
|
app_version = cmd(["git", "rev-parse", "--short", "HEAD"])
|
||||||
|
# Assembling the version is more complicated
|
||||||
try:
|
try:
|
||||||
# Start by trying to find the most recent tag
|
# Start by trying to find the most recent tag
|
||||||
last_tag = cmd(["git", "describe", "--tags", "--abbrev=0"])
|
last_tag = cmd(["git", "describe", "--tags", "--abbrev=0"])
|
||||||
@ -106,39 +110,16 @@ def get_version():
|
|||||||
version += f"-{prerelease_vn}"
|
version += f"-{prerelease_vn}"
|
||||||
|
|
||||||
# The current commit is a tagged commit if the number of commits since the last tag is zero
|
# The current commit is a tagged commit if the number of commits since the last tag is zero
|
||||||
return version, commits == 0
|
return version, app_version, commits == 0
|
||||||
|
|
||||||
|
|
||||||
def get_charts():
|
def is_changed(path, changed_paths):
|
||||||
"""
|
"""
|
||||||
Returns the list of chart directories for the repository.
|
Returns true if the given path is in the changed paths.
|
||||||
"""
|
|
||||||
if 'CHART_DIRECTORY' in os.environ:
|
|
||||||
chart_directory = pathlib.Path(os.environ['CHART_DIRECTORY']).resolve()
|
|
||||||
else:
|
|
||||||
chart_directory = pathlib.Path(__file__).resolve().parent.parent
|
|
||||||
return [path.parent for path in pathlib.Path(chart_directory).glob('**/Chart.yaml')]
|
|
||||||
|
|
||||||
|
|
||||||
def get_changed_charts(charts):
|
|
||||||
"""
|
|
||||||
Returns the list of chart directories that were changed by the last commit.
|
|
||||||
"""
|
|
||||||
# First, get the files that were changed by the last commit
|
|
||||||
commit = cmd(["git", "rev-parse", "HEAD"])
|
|
||||||
commit_files = cmd(["git", "show", "--pretty=", "--name-only", commit])
|
|
||||||
changed = [pathlib.Path(filename).resolve() for filename in commit_files.splitlines()]
|
|
||||||
# Cross-reference the charts against the changed files
|
|
||||||
return [chart for chart in charts if is_changed(chart, changed)]
|
|
||||||
|
|
||||||
|
|
||||||
def is_changed(path, changed_files):
|
|
||||||
"""
|
|
||||||
Returns true if the given path is in the changed files.
|
|
||||||
"""
|
"""
|
||||||
return any(
|
return any(
|
||||||
changed_file.is_relative_to(pathlib.Path(path).resolve())
|
changed_file.is_relative_to(pathlib.Path(path).resolve())
|
||||||
for changed_file in changed_files
|
for changed_file in changed_paths
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -189,22 +170,49 @@ def main():
|
|||||||
"""
|
"""
|
||||||
Entrypoint for the script.
|
Entrypoint for the script.
|
||||||
"""
|
"""
|
||||||
# Get the version to use for deployed charts
|
# Get the directories we will be working with
|
||||||
version, is_tag = get_version()
|
repo_root = pathlib.Path(__file__).resolve().parent.parent
|
||||||
print(f"[INFO] Charts will be published with version '{version}'")
|
if 'CHART_DIRECTORY' in os.environ:
|
||||||
# If the commit is a tagged commit, we will publish all the charts, regardless of
|
chart_directory = pathlib.Path(os.environ['CHART_DIRECTORY']).resolve()
|
||||||
# whether they have changed
|
|
||||||
charts = get_charts()
|
|
||||||
if is_tag:
|
|
||||||
print("[INFO] Detected tagged commit - publishing all charts")
|
|
||||||
else:
|
else:
|
||||||
|
chart_directory = repo_root / "charts"
|
||||||
|
if 'IMAGE_DIRECTORY' in os.environ:
|
||||||
|
image_directory = pathlib.Path(os.environ['IMAGE_DIRECTORY']).resolve()
|
||||||
|
else:
|
||||||
|
image_directory = repo_root / "utils"
|
||||||
|
|
||||||
|
# Get the version to use for deployed charts
|
||||||
|
version, app_version, is_tag = get_version()
|
||||||
|
print(f"[INFO] Charts will be published with version '{version}'")
|
||||||
|
|
||||||
|
# Get the paths that were changed by the curent commit
|
||||||
|
commit = cmd(["git", "rev-parse", "HEAD"])
|
||||||
|
commit_files = cmd(["git", "show", "--pretty=", "--name-only", commit])
|
||||||
|
changed_paths = [pathlib.Path(filename).resolve() for filename in commit_files.splitlines()]
|
||||||
|
|
||||||
|
# Get the charts in the repository
|
||||||
|
charts = [path.parent for path in chart_directory.glob('**/Chart.yaml')]
|
||||||
|
|
||||||
|
# Decide which charts we are actually going to publish
|
||||||
|
if is_tag:
|
||||||
|
# If the commit is a tag, publish all the charts regardless of changes
|
||||||
|
# so that they get the version bump
|
||||||
|
print("[INFO] Detected tagged commit - publishing all charts")
|
||||||
|
elif is_changed(image_directory, changed_paths):
|
||||||
|
# If the image was changed, publish all the charts regardless of changes
|
||||||
|
# so that they pick up the new image for any deployment jobs
|
||||||
|
print("[INFO] Image for deploy jobs has changed - publishing all charts")
|
||||||
|
else:
|
||||||
|
# In all other cases, just publish the charts that changed
|
||||||
print("[INFO] Publishing changed charts only")
|
print("[INFO] Publishing changed charts only")
|
||||||
charts = get_changed_charts(charts)
|
charts = [chart for chart in charts if is_changed(chart, changed_paths)]
|
||||||
if charts:
|
if charts:
|
||||||
print(f"[INFO] Publishing {len(charts)} charts")
|
print(f"[INFO] Publishing {len(charts)} charts")
|
||||||
else:
|
else:
|
||||||
print("[INFO] No charts to publish - exiting")
|
print("[INFO] No charts to publish - exiting")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Publish the charts and re-generate the repository index
|
||||||
publish_branch = os.environ.get('PUBLISH_BRANCH', 'gh-pages')
|
publish_branch = os.environ.get('PUBLISH_BRANCH', 'gh-pages')
|
||||||
print(f"[INFO] Charts will be published to branch '{publish_branch}'")
|
print(f"[INFO] Charts will be published to branch '{publish_branch}'")
|
||||||
with tempfile.TemporaryDirectory() as publish_directory:
|
with tempfile.TemporaryDirectory() as publish_directory:
|
||||||
@ -217,6 +225,8 @@ def main():
|
|||||||
"--dependency-update",
|
"--dependency-update",
|
||||||
"--version",
|
"--version",
|
||||||
version,
|
version,
|
||||||
|
"--app-version",
|
||||||
|
app_version,
|
||||||
"--destination",
|
"--destination",
|
||||||
publish_directory,
|
publish_directory,
|
||||||
chart_directory
|
chart_directory
|
||||||
|
60
utils/Dockerfile
Normal file
60
utils/Dockerfile
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#####
|
||||||
|
## Build specification for a container image containing tools that are useful
|
||||||
|
## for deploying applications
|
||||||
|
##
|
||||||
|
## It is designed to be run as a job inside the target cluster
|
||||||
|
#####
|
||||||
|
|
||||||
|
FROM alpine
|
||||||
|
|
||||||
|
# Install some useful tools
|
||||||
|
RUN apk add --no-cache curl jq
|
||||||
|
|
||||||
|
# Because of the version skew policy, which only guarantees compatibility with a skew
|
||||||
|
# of one minor version, we must install a bunch of kubectl versions
|
||||||
|
ARG KUBECTL_VERSIONS="v1.22.0 v1.21.4 v1.20.10 v1.19.14 v1.18.20 v1.17.17"
|
||||||
|
RUN set -ex; \
|
||||||
|
OS_ARCH="$(uname -m)"; \
|
||||||
|
case "$OS_ARCH" in \
|
||||||
|
x86_64) kubectl_arch=amd64 ;; \
|
||||||
|
aarch64) kubectl_arch=arm64 ;; \
|
||||||
|
*) false ;; \
|
||||||
|
esac; \
|
||||||
|
for kubectl_version in $KUBECTL_VERSIONS; do \
|
||||||
|
kubectl_minor_version=${kubectl_version%.*}; \
|
||||||
|
kubectl_latest_version=${kubectl_latest_version:-$kubectl_minor_version}; \
|
||||||
|
kubectl_url=https://dl.k8s.io/release/$kubectl_version/bin/linux/$kubectl_arch/kubectl; \
|
||||||
|
kubectl_exe=/usr/bin/kubectl-$kubectl_minor_version; \
|
||||||
|
curl -fsSL $kubectl_url -o $kubectl_exe; \
|
||||||
|
chmod +x $kubectl_exe; \
|
||||||
|
$kubectl_exe version --client; \
|
||||||
|
done; \
|
||||||
|
ln -s /usr/bin/kubectl-$kubectl_latest_version /usr/bin/kubectl-latest
|
||||||
|
|
||||||
|
# This script uses the latest version to discover the version of the Kubernetes
|
||||||
|
# cluster before picking the correct version to use
|
||||||
|
COPY ./kubectl-shim /usr/bin/kubectl
|
||||||
|
|
||||||
|
ARG HELM_VERSION=v3.6.3
|
||||||
|
RUN set -ex; \
|
||||||
|
OS_ARCH="$(uname -m)"; \
|
||||||
|
case "$OS_ARCH" in \
|
||||||
|
x86_64) helm_arch=amd64 ;; \
|
||||||
|
aarch64) helm_arch=arm64 ;; \
|
||||||
|
*) false ;; \
|
||||||
|
esac; \
|
||||||
|
curl -fsSL https://get.helm.sh/helm-$HELM_VERSION-linux-$helm_arch.tar.gz | \
|
||||||
|
tar -xz --strip-components 1 -C /usr/bin linux-$helm_arch/helm; \
|
||||||
|
helm version
|
||||||
|
|
||||||
|
ARG CLUSTERCTL_VERSION=v0.4.1
|
||||||
|
RUN set -ex; \
|
||||||
|
OS_ARCH="$(uname -m)"; \
|
||||||
|
case "$OS_ARCH" in \
|
||||||
|
x86_64) clusterctl_arch=amd64 ;; \
|
||||||
|
aarch64) clusterctl_arch=arm64 ;; \
|
||||||
|
*) false ;; \
|
||||||
|
esac; \
|
||||||
|
curl -fsSL https://github.com/kubernetes-sigs/cluster-api/releases/download/$CLUSTERCTL_VERSION/clusterctl-linux-$clusterctl_arch -o /usr/bin/clusterctl; \
|
||||||
|
chmod +x /usr/bin/clusterctl; \
|
||||||
|
clusterctl version
|
10
utils/kubectl-shim
Normal file
10
utils/kubectl-shim
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
#####
|
||||||
|
# Simple script that selects the correct kubectl version for the target server
|
||||||
|
#####
|
||||||
|
|
||||||
|
server_version="$(kubectl-latest version -o json | jq '"v" + .serverVersion.major + "." + .serverVersion.minor')"
|
||||||
|
exec kubectl-$server_version "$@"
|
Loading…
x
Reference in New Issue
Block a user