Skip to content

Commit 0e9254a

Browse files
committed
chore: enhance the asciinema demo creation script
1 parent b77b135 commit 0e9254a

File tree

4 files changed

+306
-27
lines changed

4 files changed

+306
-27
lines changed

Makefile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,49 @@ generate-charts: build ## Re-generate the helm chart testdata and docs samples
108108
(cd docs/book/src/cronjob-tutorial/testdata/project && ../../../../../../bin/kubebuilder edit --plugins=helm/v1-alpha)
109109
(cd docs/book/src/multiversion-tutorial/testdata/project && ../../../../../../bin/kubebuilder edit --plugins=helm/v1-alpha)
110110

111+
.PHONY: update-demo
112+
update-demo: ## Record and update the Kubebuilder demo using Asciinema
113+
@echo "Recording new Kubebuilder demo with Asciinema..."
114+
@echo "Prerequisites: asciinema, svg-term, kind, and kubectl must be installed"
115+
@which asciinema > /dev/null || (echo "Error: asciinema not found. Install with: brew install asciinema" && exit 1)
116+
@which svg-term > /dev/null || (echo "Error: svg-term not found. Install with: npm install -g svg-term-cli" && exit 1)
117+
@which kind > /dev/null || (echo "Error: kind not found. Install with: brew install kind" && exit 1)
118+
@which kubectl > /dev/null || (echo "Error: kubectl not found. Install from: https://kubernetes.io/docs/tasks/tools/install-kubectl/" && exit 1)
119+
@echo "Setting up Kind cluster for demo..."
120+
@./scripts/demo/setup-kind.sh
121+
@echo "Verifying cluster connection..."
122+
@kubectl cluster-info --context kind-kubebuilder-demo > /dev/null
123+
@echo "Cleaning up any previous recording files..."
124+
@rm -rf /tmp/kb-demo-recording
125+
@mkdir -p /tmp/kb-demo-recording
126+
@echo "Starting demo recording in 3 seconds..."
127+
@sleep 3
128+
@cd /tmp/kb-demo-recording && asciinema rec --command "$(shell pwd)/scripts/demo/run.sh" --env "DEMO_AUTO_RUN=1" --title "Kubebuilder Demo" --idle-time-limit 2 kb-demo.cast
129+
@echo "Converting recording to SVG..."
130+
@VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v4.0.0"); \
131+
svg-term --in=/tmp/kb-demo-recording/kb-demo.cast --out=docs/gif/kb-demo.$${VERSION}.svg --window --width=120 --height=30
132+
@VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v4.0.0"); \
133+
echo "Demo updated! New file: docs/gif/kb-demo.$${VERSION}.svg"
134+
@echo "Updating README.md with new demo..."
135+
@VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "v4.0.0"); \
136+
sed -i '' 's|docs/gif/kb-demo\.v[^)]*\.svg|docs/gif/kb-demo.'$${VERSION}'.svg|g' README.md
137+
@echo "README.md updated with new demo file."
138+
@echo "Cleaning up temporary files..."
139+
@rm -rf /tmp/kb-demo-recording
140+
@echo "To clean up the demo cluster, run: make clean-demo"
141+
142+
.PHONY: setup-demo-cluster
143+
setup-demo-cluster: ## Set up Kind cluster for Kubebuilder demo
144+
@./scripts/demo/setup-kind.sh
145+
146+
.PHONY: clean-demo
147+
clean-demo: ## Clean up the demo Kind cluster and temporary directories
148+
@echo "Cleaning up demo cluster..."
149+
@kind delete cluster --name kubebuilder-demo || echo "Demo cluster was not found or already deleted"
150+
@echo "Cleaning up temporary demo directories..."
151+
@rm -rf /tmp/kubebuilder-demo-project /tmp/kb-demo-recording
152+
@echo "Demo cleanup completed"
153+
111154
.PHONY: check-docs
112155
check-docs: ## Run the script to ensure that the docs are updated
113156
./hack/docs/check.sh

scripts/demo/README.md

Lines changed: 101 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,120 @@
1-
This directory contains scripts to run a quick demo of Kubebuilder.
1+
# Kubebuilder Demo
22

3-
Steps to run demo:
3+
This directory contains scripts to run a comprehensive demo of Kubebuilder features with a local Kind cluster.
4+
5+
## Quick Demo (Manual)
6+
7+
To run the demo manually:
48

59
```sh
610
mkdir /tmp/kb-demo
711
cd /tmp/kb-demo
8-
DEMO_AUTO_RUN=1 ./run.sh
12+
DEMO_AUTO_RUN=1 /path/to/kubebuilder/scripts/demo/run.sh
13+
```
14+
15+
## Automated Demo Recording
16+
17+
To automatically record and update the demo using Asciinema:
18+
19+
```sh
20+
# From the root of the Kubebuilder repository
21+
make update-demo
22+
```
23+
24+
This will:
25+
1. Check for required dependencies (asciinema, svg-term, kind, kubectl)
26+
2. Set up a Kind cluster for the demo
27+
3. Record the demo session automatically
28+
4. Convert the recording to SVG format
29+
5. Update the demo file in `docs/gif/kb-demo.${VERSION}.svg`
30+
6. Clean up temporary files
31+
32+
## Setup Demo Cluster Only
33+
34+
If you just want to set up the Kind cluster for testing:
935

36+
```sh
37+
make setup-demo-cluster
1038
```
1139

12-
Instructions for producing the demo movie:
40+
## Clean Up Demo Cluster
41+
42+
To remove the demo Kind cluster when done:
1343

1444
```sh
45+
make clean-demo
46+
```
47+
48+
## Prerequisites for Recording
49+
50+
- `kind`: For creating local Kubernetes clusters
51+
```sh
52+
# macOS
53+
brew install kind
54+
# Linux
55+
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
56+
chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind
57+
```
58+
59+
- `kubectl`: For interacting with Kubernetes
60+
```sh
61+
# macOS
62+
brew install kubectl
63+
# Other platforms: https://kubernetes.io/docs/tasks/tools/install-kubectl/
64+
```
65+
66+
- `asciinema`: For recording terminal sessions
67+
```sh
68+
# macOS
69+
brew install asciinema
70+
# Ubuntu/Debian
71+
sudo apt-get install asciinema
72+
```
73+
74+
- `svg-term`: For converting recordings to SVG
75+
```sh
76+
npm install -g svg-term-cli
77+
```
78+
79+
## What the Demo Shows
80+
81+
The current demo showcases:
82+
83+
1. **Cluster Setup**: Creates a local Kind cluster for testing
84+
2. **Installation**: Installing Kubebuilder from scratch
85+
3. **Project Initialization**: Creating a new operator project
86+
4. **API Creation**: Creating APIs with validation markers
87+
5. **Plugin System**: Using the deploy-image plugin
88+
6. **Modern Features**:
89+
- Validation markers (`+kubebuilder:validation`)
90+
- Multiple APIs in one project
91+
- Generated CRDs with OpenAPI schemas
92+
- Sample resource management
93+
7. **Development Workflow**: Install CRDs, apply samples, run controller
94+
8. **Cluster Integration**: Full integration with Kubernetes cluster
95+
96+
## Manual Recording Instructions (Legacy)
97+
98+
If you prefer to record manually:
99+
100+
```sh
101+
# Set up Kind cluster first
102+
./scripts/demo/setup-kind.sh
15103

16104
# Create temporary directory
17105
mkdir /tmp/kb-demo
18106
cd /tmp/kb-demo
19107

20-
asciinema rec
21-
<path-to-KB-repo>/scripts/demo/run.sh
22-
23-
# After each step, press <Enter> to proceed to the next step
108+
# Start recording
109+
asciinema rec --title "Kubebuilder Demo" kb-demo.cast
24110

25-
<CTRL-C> to terminate the script
26-
<CTRL-D> to terminate the asciinema recording
27-
<CTRL-C> to save the recording locally
111+
# Run the demo script
112+
DEMO_AUTO_RUN=1 /path/to/kubebuilder/scripts/demo/run.sh
28113

29-
# Edit the recorded file by editing the controller-gen path
30-
# Once you are happy with the recording, use svg-term program to generate the svg
114+
# Stop recording with Ctrl+C when done
115+
# Convert to SVG
116+
svg-term --in=kb-demo.cast --out=kb-demo.svg --window --width=120 --height=30
31117

32-
svg-term --in=<cast-file-path> --out demo.svg --window
118+
# Clean up when done
119+
kind delete cluster --name kubebuilder-demo
33120
```

scripts/demo/run.sh

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,72 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16+
# Set up working directory in /tmp for clean demo
17+
cd /tmp
18+
rm -rf kubebuilder-demo-project
19+
mkdir kubebuilder-demo-project
20+
cd kubebuilder-demo-project
21+
1622
clear
1723
. $(dirname ${BASH_SOURCE})/util.sh
1824

19-
desc "Initialize Go modules"
20-
run "go mod init demo.kubebuilder.io"
25+
desc "Check if Kubebuilder is installed"
26+
run "kubebuilder version"
27+
28+
desc "Initialize Go modules for our project"
29+
run "go mod init demo.kubebuilder.io/webapp-operator"
30+
31+
desc "Initialize a new Kubebuilder project with custom domain"
32+
run "kubebuilder init --domain demo.kubebuilder.io --repo demo.kubebuilder.io/webapp-operator"
33+
clear
34+
35+
desc "Examine the scaffolded project structure"
36+
run "tree -L 2 ."
37+
clear
38+
39+
desc "Create our first API - a Guestbook with validation markers"
40+
run "kubebuilder create api --group webapp --version v1 --kind Guestbook"
41+
clear
2142

22-
desc "Let's initialize the project"
23-
run "kubebuilder init --domain tutorial.kubebuilder.io"
43+
desc "Let's explore the generated files structure"
44+
run "tree api/ internal/controller/"
2445
clear
2546

26-
desc "Examine scaffolded files..."
27-
run "tree ."
47+
desc "Look at the API definition - notice the validation markers"
48+
run "cat api/v1/guestbook_types.go"
2849
clear
2950

30-
desc "Create our custom cronjob api"
31-
run "kubebuilder create api --group batch --version v1 --kind CronJob"
51+
desc "Now let's create a second API using the modern deploy-image plugin"
52+
run "kubebuilder create api --group webapp --version v1alpha1 --kind Busybox --image=busybox:1.36.1 --plugins=deploy-image/v1-alpha"
3253
clear
3354

34-
desc "Let's take a look at the API and Controller files"
35-
run "tree ./api ./internal/controller"
55+
desc "Generate manifests including CRDs with OpenAPI validation schemas"
56+
run "make manifests"
57+
58+
desc "Examine the generated CRD with validation rules"
59+
run "head -60 config/crd/bases/webapp.demo.kubebuilder.io_guestbooks.yaml"
3660
clear
3761

38-
desc "Install CRDs in Kubernetes cluster"
62+
desc "Install our Custom Resource Definitions into the cluster"
3963
run "make install"
64+
65+
desc "Verify our CRDs are installed"
66+
run "kubectl get crd --context kind-kubebuilder-demo"
67+
clear
68+
69+
desc "Look at the sample resources that were generated"
70+
run "ls config/samples/"
71+
72+
desc "Show a sample resource"
73+
run "cat config/samples/webapp_v1_guestbook.yaml"
74+
clear
75+
76+
desc "Apply the sample resources to test our APIs"
77+
run "kubectl apply -k config/samples/webapp_v1alpha1_busybox.yaml --context kind-kubebuilder-demo"
78+
79+
desc "Check the created custom resources in the cluster"
80+
run "kubectl get guestbooks,busyboxes -A --context kind-kubebuilder-demo"
4081
clear
4182

42-
desc "Run controller manager locally"
43-
run "make run"
83+
desc "Demo completed! The controller can be run with 'make run'"
84+
run "echo 'To run the controller: make run'"

scripts/demo/setup-kind.sh

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2025 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -e
18+
19+
CLUSTER_NAME="kubebuilder-demo"
20+
21+
echo "Setting up Kind cluster for Kubebuilder demo..."
22+
23+
# Check if Kind is installed
24+
if ! command -v kind &> /dev/null; then
25+
echo "Kind is not installed. Installing Kind..."
26+
# Install Kind based on OS
27+
case "$(uname -s)" in
28+
Darwin)
29+
if command -v brew &> /dev/null; then
30+
brew install kind
31+
else
32+
echo "Please install Homebrew first or install Kind manually: https://kind.sigs.k8s.io/docs/user/quick-start/#installation"
33+
exit 1
34+
fi
35+
;;
36+
Linux)
37+
# For AMD64 / x86_64
38+
[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
39+
# For ARM64
40+
[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-arm64
41+
chmod +x ./kind
42+
sudo mv ./kind /usr/local/bin/kind
43+
;;
44+
*)
45+
echo "Unsupported OS. Please install Kind manually: https://kind.sigs.k8s.io/docs/user/quick-start/#installation"
46+
exit 1
47+
;;
48+
esac
49+
fi
50+
51+
# Check if kubectl is installed
52+
if ! command -v kubectl &> /dev/null; then
53+
echo "kubectl is not installed. Please install kubectl first."
54+
echo "Visit: https://kubernetes.io/docs/tasks/tools/install-kubectl/"
55+
exit 1
56+
fi
57+
58+
# Check if cluster already exists
59+
if kind get clusters | grep -q "^${CLUSTER_NAME}$"; then
60+
echo "Kind cluster '${CLUSTER_NAME}' already exists."
61+
echo "Switching kubectl context to existing cluster..."
62+
kubectl cluster-info --context kind-${CLUSTER_NAME}
63+
else
64+
echo "Creating Kind cluster '${CLUSTER_NAME}'..."
65+
66+
# Create Kind config for the demo
67+
cat > /tmp/kind-config.yaml <<EOF
68+
kind: Cluster
69+
apiVersion: kind.x-k8s.io/v1alpha4
70+
name: ${CLUSTER_NAME}
71+
nodes:
72+
- role: control-plane
73+
kubeadmConfigPatches:
74+
- |
75+
kind: InitConfiguration
76+
nodeRegistration:
77+
kubeletExtraArgs:
78+
node-labels: "ingress-ready=true"
79+
extraPortMappings:
80+
- containerPort: 80
81+
hostPort: 80
82+
protocol: TCP
83+
- containerPort: 443
84+
hostPort: 443
85+
protocol: TCP
86+
EOF
87+
88+
# Create the cluster
89+
kind create cluster --config=/tmp/kind-config.yaml --wait=300s
90+
91+
# Clean up config file
92+
rm /tmp/kind-config.yaml
93+
94+
echo "Kind cluster '${CLUSTER_NAME}' created successfully!"
95+
fi
96+
97+
# Verify cluster is ready
98+
echo "Verifying cluster is ready..."
99+
kubectl cluster-info --context kind-${CLUSTER_NAME}
100+
kubectl get nodes --context kind-${CLUSTER_NAME}
101+
102+
echo ""
103+
echo "Kind cluster is ready for the Kubebuilder demo!"
104+
echo "Cluster name: ${CLUSTER_NAME}"
105+
echo "Context: kind-${CLUSTER_NAME}"
106+
echo ""
107+
echo "To delete the cluster when done:"
108+
echo " kind delete cluster --name ${CLUSTER_NAME}"

0 commit comments

Comments
 (0)