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():
|
||||
"""
|
||||
Returns a (version, is_tag) tuple where version is a SemVer-compliant version based on Git information
|
||||
for the current working directory and is_tag is true iff the current commit is a tagged commit.
|
||||
Returns a (version, app_version, is_tag) tuple where version is a SemVer-compliant version based on
|
||||
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
|
||||
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:
|
||||
# Start by trying to find the most recent tag
|
||||
last_tag = cmd(["git", "describe", "--tags", "--abbrev=0"])
|
||||
@ -106,39 +110,16 @@ def get_version():
|
||||
version += f"-{prerelease_vn}"
|
||||
|
||||
# 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.
|
||||
"""
|
||||
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.
|
||||
Returns true if the given path is in the changed paths.
|
||||
"""
|
||||
return any(
|
||||
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.
|
||||
"""
|
||||
# Get the version to use for deployed charts
|
||||
version, is_tag = get_version()
|
||||
print(f"[INFO] Charts will be published with version '{version}'")
|
||||
# If the commit is a tagged commit, we will publish all the charts, regardless of
|
||||
# whether they have changed
|
||||
charts = get_charts()
|
||||
if is_tag:
|
||||
print("[INFO] Detected tagged commit - publishing all charts")
|
||||
# Get the directories we will be working with
|
||||
repo_root = pathlib.Path(__file__).resolve().parent.parent
|
||||
if 'CHART_DIRECTORY' in os.environ:
|
||||
chart_directory = pathlib.Path(os.environ['CHART_DIRECTORY']).resolve()
|
||||
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")
|
||||
charts = get_changed_charts(charts)
|
||||
charts = [chart for chart in charts if is_changed(chart, changed_paths)]
|
||||
if charts:
|
||||
print(f"[INFO] Publishing {len(charts)} charts")
|
||||
else:
|
||||
print("[INFO] No charts to publish - exiting")
|
||||
return
|
||||
|
||||
# Publish the charts and re-generate the repository index
|
||||
publish_branch = os.environ.get('PUBLISH_BRANCH', 'gh-pages')
|
||||
print(f"[INFO] Charts will be published to branch '{publish_branch}'")
|
||||
with tempfile.TemporaryDirectory() as publish_directory:
|
||||
@ -217,6 +225,8 @@ def main():
|
||||
"--dependency-update",
|
||||
"--version",
|
||||
version,
|
||||
"--app-version",
|
||||
app_version,
|
||||
"--destination",
|
||||
publish_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