Skip to content

Commit

Permalink
feat: add image builds
Browse files Browse the repository at this point in the history
  • Loading branch information
mnaser committed Oct 25, 2022
1 parent eff8874 commit 2d5248b
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 12 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/images.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: images
on:
pull_request:
paths:
- .github/workflows/images.yml
- magnum_cluster_api/cmd/image_builder.py
push:
branches:
- main
paths:
- .github/workflows/images.yml
- magnum_cluster_api/cmd/image_builder.py

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
kubernetes-version:
- v1.23.13
- v1.24.7
- v1.25.3
steps:
- name: Checkout project
uses: actions/[email protected]

- name: Install Poetry
run: pipx install poetry

- name: Setup Python
uses: actions/[email protected]
with:
cache: poetry

- name: Install dependencies
run: poetry install --no-interaction

- name: Build image
run: poetry run magnum-cluster-api-image-builder --version ${{ matrix.kubernetes-version }}

# TODO: upload to swift if push to main
47 changes: 36 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# `magnum-cluster-api`

## Images

The images are built and published to an object storage bucket hosted at the
[VEXXHOST](https://vexxhost.com) public cloud. These images are built and
published for the latest stable release of Kubernetes.

### Pre-built images

You can find the pre-built images for the latest stable release of Kubernetes
at the following URL:

* [v1.23.13](https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/ubuntu-2004-v1.23.13.qcow2)
* [v1.24.7](https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/ubuntu-2004-v1.24.7.qcow2)
* [v1.25.3](https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/ubuntu-2004-v1.25.3.qcow2)

### Building images

The Cluster API driver for Magnum provides a tool in order to build images, you
can use it by installing the `magnum-cluster-api` package and running the
the following command:

```bash
magnum-cluster-api-image-builder
```

## Testing & Development

In order to be able to test and develop the `magnum-cluster-api` project, you
Expand Down Expand Up @@ -53,15 +78,15 @@ steps to be able to test and develop the project.

## TODO

- audit all labels + options to make sure it works
- cluster resize
- cluster upgrade
- [autohealing](https://cluster-api.sigs.k8s.io/tasks/automated-machine-management/healthchecking.html)
* audit all labels + options to make sure it works
* cluster resize
* cluster upgrade
* [autohealing](https://cluster-api.sigs.k8s.io/tasks/automated-machine-management/healthchecking.html)
with `auto_healing_enabled`
- [autoscaling](https://cluster-api.sigs.k8s.io/tasks/automated-machine-management/autoscaling.html)
- boot from volume
- custom image location
- ingress
- k8s_keystone_auth_tag
- kube_dashboard_enabled
- monitoring (maybe?)
* [autoscaling](https://cluster-api.sigs.k8s.io/tasks/automated-machine-management/autoscaling.html)
* boot from volume
* custom image location
* ingress
* k8s_keystone_auth_tag
* kube_dashboard_enabled
* monitoring (maybe?)
Empty file.
123 changes: 123 additions & 0 deletions magnum_cluster_api/cmd/image_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import json
import os
import subprocess
import tarfile
import tempfile
import textwrap
import zlib
from pathlib import Path

import click
import requests

QEMU_PACKAGES = [
"qemu-kvm",
"libvirt-daemon-system",
"libvirt-clients",
"virtinst",
"cpu-checker",
"libguestfs-tools",
"libosinfo-bin",
]


@click.command()
@click.option(
"--operating-system",
show_default=True,
default="ubuntu-2004",
type=click.Choice(["ubuntu-2004"]),
help="Operating system to build image for",
)
@click.option(
"--version",
show_default=True,
default="1.25.3",
help="Kubernetes version",
)
@click.option(
"--image-builder-version",
show_default=True,
default="v0.1.13",
help="Image builder tag (or commit) to use for building image",
)
def main(version, image_builder_version):
ib_path = f"/tmp/image-builder-{image_builder_version}"
output = f"ubuntu-2004-kube-v{version}"

target = f"{ib_path}/images/capi/output/{output}/{output}"
if os.path.exists(target):
print(f"Image already exists: {target}")
return

click.echo("- Install QEMU packages")
subprocess.run(
["sudo", "/usr/bin/apt", "install", "-y"] + QEMU_PACKAGES, check=True
)

click.echo("- Add current user to KVM group")
subprocess.run(
["sudo", "/usr/sbin/usermod", "-a", "-G", "kvm", os.getlogin()], check=True
)

click.echo("- Update permissions for the KVM device")
subprocess.run(["sudo", "/bin/chown", "root:kvm", "/dev/kvm"], check=True)

# Setup our stream decompressor
dec = zlib.decompressobj(32 + zlib.MAX_WBITS)

click.echo("- Download image-builder")
path = f"{ib_path}.tar"
with requests.get(
f"https://github.com/kubernetes-sigs/image-builder/tarball/{image_builder_version}",
stream=True,
) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
rv = dec.decompress(chunk)
if rv:
f.write(rv)

click.echo("- Extract image-builder")
with tarfile.open(path) as tar:
members = []
for member in tar.getmembers():
p = Path(member.path)
member.path = p.relative_to(*p.parts[:1])
members.append(member)

tar.extractall(ib_path, members=members)

click.echo("- Create customization file")
kubernetes_series = ".".join(version.split(".")[0:2])
customization = {
"kubernetes_deb_version": f"{version}-00",
"kubernetes_semver": f"v{version}",
"kubernetes_series": f"v{kubernetes_series}",
}
with tempfile.NamedTemporaryFile(suffix=".json") as fp:
fp.write(json.dumps(customization).encode("utf-8"))
fp.flush()

click.echo("- Build image")
subprocess.run(
[
"/usr/bin/newgrp",
"kvm",
],
input=textwrap.dedent(
f"""\
/usr/bin/make \
-C \
{ib_path}/images/capi \
build-qemu-ubuntu-2004
"""
).encode("utf-8"),
env={
**os.environ,
**{
"PACKER_VAR_FILES": fp.name,
},
},
)
29 changes: 28 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ packages = [{include = "magnum_cluster_api"}]
[tool.poetry.dependencies]
python = "^3.8"
pykube-ng = "^22.9.0"
click = "*"
requests = "*"

[build-system]
requires = ["setuptools", "poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
magnum-cluster-api-image-builder = "magnum_cluster_api.cmd.image_builder:main"

[tool.poetry.plugins."magnum.drivers"]
"k8s_cluster_api_ubuntu_focal" = "magnum_cluster_api.driver:UbuntuFocalDriver"
18 changes: 18 additions & 0 deletions tools/sync-k8s-image-builds
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash -e

RELEASES=(
"v1.23"
"v1.24"
"v1.25"
)

# Loop over all of the releases and get the latest patch release
for RELEASE in ${RELEASES[@]}; do
LATEST_TAG=$(gh release list --repo kubernetes/kubernetes | grep ${RELEASE} | head -1 | awk '{ print $2 }')

LINE="* [${LATEST_TAG}](https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/ubuntu-2004-${LATEST_TAG}.qcow2)"
sed -i "s%* \[${RELEASE}.*%${LINE}%g" README.md

LINE="- ${LATEST_TAG}"
sed -i "s%- ${RELEASE}.*%${LINE}%g" .github/workflows/images.yml
done

0 comments on commit 2d5248b

Please sign in to comment.