Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,29 @@ local-env-setup: ## Setup complete local development environment with Kind clust
@echo "Or run with MCP inspector:"
@echo " npx @modelcontextprotocol/inspector@latest \$$(pwd)/$(BINARY_NAME) --config _output/config.toml"

.PHONY: local-env-setup-kubevirt

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based on prior internal discussions, we might want to remove the local-env-setup and others, and leave the more local granular tasks (kind, keycloak, kiali, and kubevirt)

cc @matzew

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manusa I don't mind either way but maybe for now that's something we could handle in a follow up that also removes these local-env-setup targets?

local-env-setup-kubevirt: ## Setup complete local development environment with Kind cluster and KubeVirt
@echo "========================================="
@echo "Kubernetes MCP Server - Local Setup"
@echo " with KubeVirt"
@echo "========================================="
$(MAKE) kind-create-cluster
$(MAKE) kubevirt-install
$(MAKE) build
@echo ""
@echo "========================================="
@echo "Local environment ready!"
@echo "========================================="
@echo ""
@echo "Run the MCP server with:"
@echo " ./$(BINARY_NAME)"
@echo ""
@echo "Or run with MCP inspector:"
@echo " npx @modelcontextprotocol/inspector@latest \$$(pwd)/$(BINARY_NAME)"
@echo ""
@echo "KubeVirt is now available!"
@echo "Check status with: make kubevirt-status"

.PHONY: local-env-teardown
local-env-teardown: ## Tear down the local Kind cluster
$(MAKE) kind-delete-cluster
Expand Down
81 changes: 81 additions & 0 deletions build/kubevirt.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# KubeVirt installation and management

# KubeVirt version configuration
KUBEVIRT_VERSION ?= v1.7.0
CDI_VERSION ?= v1.64.0
Comment thread
lyarwood marked this conversation as resolved.

# Detect if we're using a released version or main/latest
KUBEVIRT_RELEASE_URL = https://github.com/kubevirt/kubevirt/releases/download/$(KUBEVIRT_VERSION)
CDI_RELEASE_URL = https://github.com/kubevirt/containerized-data-importer/releases/download/$(CDI_VERSION)

##@ KubeVirt

.PHONY: kubevirt-install
kubevirt-install: ## Install KubeVirt and CDI on the cluster
@echo "========================================="
@echo "Installing KubeVirt $(KUBEVIRT_VERSION)"
@echo "========================================="
@echo ""
@echo "Installing KubeVirt operator..."
@kubectl apply -f $(KUBEVIRT_RELEASE_URL)/kubevirt-operator.yaml
@echo ""
@echo "Installing KubeVirt CR..."
@kubectl apply -f $(KUBEVIRT_RELEASE_URL)/kubevirt-cr.yaml
@echo ""
@echo "Waiting for KubeVirt to become ready (this can take a few minutes)..."
@kubectl -n kubevirt wait kv kubevirt --for condition=Available --timeout=15m
Comment thread
lyarwood marked this conversation as resolved.
@echo "✅ KubeVirt is ready"
@echo ""
@echo "Installing CDI (Containerized Data Importer) $(CDI_VERSION)..."
@kubectl apply -f $(CDI_RELEASE_URL)/cdi-operator.yaml
@kubectl apply -f $(CDI_RELEASE_URL)/cdi-cr.yaml
@echo ""
@echo "Waiting for CDI to become ready..."
@kubectl wait --for=condition=Available cdi/cdi -n cdi --timeout=5m
@echo "✅ CDI is ready"
@echo ""
@echo "========================================="
@echo "KubeVirt Installation Complete"
@echo "========================================="
@echo ""
@echo "KubeVirt version: $(KUBEVIRT_VERSION)"
@echo "CDI version: $(CDI_VERSION)"
@echo ""
@echo "Verify installation with:"
@echo " kubectl get kubevirt -n kubevirt"
@echo " kubectl get cdi -n cdi"
@echo ""

.PHONY: kubevirt-uninstall
kubevirt-uninstall: ## Uninstall KubeVirt and CDI from the cluster
@echo "Uninstalling KubeVirt and CDI..."
@kubectl delete -f $(KUBEVIRT_RELEASE_URL)/kubevirt-cr.yaml --ignore-not-found
@kubectl delete -f $(KUBEVIRT_RELEASE_URL)/kubevirt-operator.yaml --ignore-not-found
@kubectl delete -f $(CDI_RELEASE_URL)/cdi-cr.yaml --ignore-not-found
@kubectl delete -f $(CDI_RELEASE_URL)/cdi-operator.yaml --ignore-not-found
@echo "✅ KubeVirt and CDI uninstalled"

.PHONY: kubevirt-status
kubevirt-status: ## Show KubeVirt and CDI status
@echo "========================================="
@echo "KubeVirt Status"
@echo "========================================="
@echo ""
@echo "KubeVirt:"
@kubectl get kubevirt -n kubevirt -o wide || { echo "KubeVirt not installed"; exit 1; }
@echo ""
@echo "CDI:"
@kubectl get cdi -n cdi -o wide || { echo "CDI not installed"; exit 1; }
@echo ""
@echo "KubeVirt Pods:"
@kubectl get pods -n kubevirt
@echo ""
@echo "CDI Pods:"
@kubectl get pods -n cdi
@echo ""
@echo "VirtualMachines (all namespaces):"
@kubectl get virtualmachines --all-namespaces || echo "No VirtualMachines found"
@echo ""
Comment thread
lyarwood marked this conversation as resolved.
@echo "VirtualMachineInstances (all namespaces):"
@kubectl get virtualmachineinstances --all-namespaces || echo "No VirtualMachineInstances found"
@echo ""
6 changes: 3 additions & 3 deletions evals/tasks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ This directory hosts the reusable task scenarios that power MCP evaluations for
## Task Families

- [Kubernetes tasks](kubernetes/) – core cluster workflows such as creating pods, fixing deployments, managing RBAC, or debugging state issues.
- [Kiali tasks](kiali/) – service-mesh and observability workflows that exercise the Kiali MCP toolset (Istio config, topology, mesh health, tracing).
- [Kiali tasks](kiali/) – service-mesh and observability workflows that exercise the Kiali MCP toolset (Istio config, topology, mesh health, tracing).
- [KubeVirt tasks](kubevirt/) – virtual machine management workflows that exercise the KubeVirt MCP toolset (VM creation, lifecycle management, resource updates).

## Anatomy of a Task

Every subdirectory under `kubernetes/` or `kiali/` defines a single scenario:
Every subdirectory under `kubernetes/`, `kiali/`, or `kubevirt/` defines a single scenario:

1. `*.yaml` – declarative description consumed by the evaluation harness (prompts, success criteria, required tools).
2. `setup.sh` / `verify.sh` / `cleanup.sh` – shell hooks (optional) that prime the cluster, assert post-conditions, and reset resources so tasks stay idempotent.
Expand All @@ -33,4 +34,3 @@ When a new MCP toolset lands , keep its evaluations isolated by creating a sibli
3. Any shared fixtures the stack needs (place them in a `shared/` subdirectory if multiple scenarios reuse them).

This structure keeps task stacks discoverable and lets eval harnesses target toolset-specific workflows without mixing concerns from the core Kubernetes or Kiali libraries.

60 changes: 60 additions & 0 deletions evals/tasks/kubevirt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# KubeVirt Task Stack

KubeVirt-focused MCP tasks live here. Each folder under this directory represents a self-contained scenario that exercises the KubeVirt toolset (virtual machine creation, lifecycle management, troubleshooting).

## Adding a New Task

1. Create a new subdirectory (e.g., `create-vm-foo/`) and place the scenario YAML plus any helper scripts or artifacts inside it.
2. Make sure the YAML's `metadata` block includes `name` and `difficulty` so it shows up correctly in the catalog below.
3. Keep prompts concise and action-oriented; verification commands should rely on KubeVirt resources and helper functions whenever possible.

## Tasks Defined

### VM Creation

- **[easy] create-vm-basic** - Create a basic Fedora virtual machine
- **Prompt:** *Please create a Fedora virtual machine named test-vm in the vm-test namespace.*

- **[easy] create-vm-ubuntu** - Create an Ubuntu virtual machine
- **Prompt:** *Create an Ubuntu virtual machine named ubuntu-vm in the vm-test namespace.*

- **[easy] create-vm-with-instancetype** - Create a VM using VirtualMachineInstancetype
Comment thread
lyarwood marked this conversation as resolved.
- **Prompt:** *Create a Fedora virtual machine with specific instance types and preferences.*

- **[easy] create-vm-with-size** - Create a VM with specific size requirements
Comment thread
lyarwood marked this conversation as resolved.
- **Prompt:** *Create a virtual machine with custom CPU and memory specifications.*

### VM Lifecycle Management

- **[medium] pause-vm** - Pause a running virtual machine
- **Prompt:** *Please pause the virtual machine named paused-vm in the vm-test namespace.*

- **[medium] delete-vm** - Delete a virtual machine
- **Prompt:** *Please delete the virtual machine named deleted-vm in the vm-test namespace.*

### VM Modification

- **[hard] update-vm-resources** - Update VM CPU and memory resources
- **Prompt:** *A VirtualMachine named test-vm-update exists in the vm-test namespace. It currently has 1 vCPU and 2Gi of memory. Please update the VirtualMachine to add an additional vCPU (making it 2 vCPUs total) and increase the memory to at least 3Gi.*

## Helper Scripts

Many tasks rely on helper scripts located in `evals/tasks/kubevirt/helpers/`:

- `verify-vm.sh` - Common VM verification functions used across multiple test scenarios

## Running Tasks

These tasks are designed to be used with the gevals evaluation framework. Each task includes:
Comment thread
lyarwood marked this conversation as resolved.

- **setup** - Prepares the test environment (creates namespace, sets up initial VM state)
- **verify** - Validates the expected outcome after the agent completes the task
- **cleanup** - Removes resources created during the test
- **prompt** - The instruction given to the AI agent

Example workflow:

1. Setup creates the initial state
2. Agent receives the prompt and executes actions using MCP tools
3. Verify checks if the agent accomplished the goal
4. Cleanup removes test resources
37 changes: 37 additions & 0 deletions evals/tasks/kubevirt/create-vm-basic/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
kind: Task
Comment thread
lyarwood marked this conversation as resolved.
metadata:
name: "create-basic-vm"
difficulty: easy
steps:
setup:
inline: |-
#!/usr/bin/env bash
NS="${EVAL_NAMESPACE:-vm-test}"
kubectl delete namespace "$NS" --ignore-not-found
kubectl create namespace "$NS"
verify:
inline: |-
#!/usr/bin/env bash
source evals/tasks/kubevirt/helpers/verify-vm.sh
NS="${EVAL_NAMESPACE:-vm-test}"

# Wait for VirtualMachine to be created
verify_vm_exists "test-vm" "$NS" || exit 1
Comment thread
lyarwood marked this conversation as resolved.

# Verify container disk is Fedora
verify_container_disk "test-vm" "$NS" "fedora" || exit 1

# Verify runStrategy is set and deprecated 'running' field is not used
verify_run_strategy "test-vm" "$NS" || exit 1
verify_no_deprecated_running_field "test-vm" "$NS" || exit 1

echo "All validations passed"
exit 0
cleanup:
inline: |-
#!/usr/bin/env bash
NS="${EVAL_NAMESPACE:-vm-test}"
kubectl delete virtualmachine test-vm -n "$NS" --ignore-not-found
kubectl delete namespace "$NS" --ignore-not-found
prompt:
inline: Create a Fedora virtual machine named test-vm in the ${EVAL_NAMESPACE:-vm-test} namespace.
37 changes: 37 additions & 0 deletions evals/tasks/kubevirt/create-vm-ubuntu/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
kind: Task
metadata:
name: "create-ubuntu-vm"
difficulty: easy
steps:
setup:
inline: |-
#!/usr/bin/env bash
NS="${EVAL_NAMESPACE:-vm-test}"
kubectl delete namespace "$NS" --ignore-not-found
kubectl create namespace "$NS"
verify:
inline: |-
#!/usr/bin/env bash
source evals/tasks/kubevirt/helpers/verify-vm.sh
NS="${EVAL_NAMESPACE:-vm-test}"

# Wait for VirtualMachine to be created
verify_vm_exists "ubuntu-vm" "$NS" || exit 1

# Verify container disk is Ubuntu
verify_container_disk "ubuntu-vm" "$NS" "ubuntu" || exit 1

# Verify runStrategy is set and deprecated 'running' field is not used
verify_run_strategy "ubuntu-vm" "$NS" || exit 1
verify_no_deprecated_running_field "ubuntu-vm" "$NS" || exit 1

echo "All validations passed"
exit 0
cleanup:
inline: |-
#!/usr/bin/env bash
NS="${EVAL_NAMESPACE:-vm-test}"
kubectl delete virtualmachine ubuntu-vm -n "$NS" --ignore-not-found
kubectl delete namespace "$NS" --ignore-not-found
prompt:
inline: Create an Ubuntu virtual machine named ubuntu-vm in the ${EVAL_NAMESPACE:-vm-test} namespace.
43 changes: 43 additions & 0 deletions evals/tasks/kubevirt/create-vm-with-instancetype/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
kind: Task
metadata:
name: "create-vm-with-instancetype"
difficulty: easy
steps:
setup:
inline: |-
#!/usr/bin/env bash
NS="${EVAL_NAMESPACE:-vm-test}"
kubectl delete namespace "$NS" --ignore-not-found
kubectl create namespace "$NS"
verify:
inline: |-
#!/usr/bin/env bash
source evals/tasks/kubevirt/helpers/verify-vm.sh
NS="${EVAL_NAMESPACE:-vm-test}"

# Wait for VirtualMachine to be created
verify_vm_exists "test-vm-instancetype" "$NS" || exit 1

# Verify that it has the specific instancetype reference (u1.medium)
verify_instancetype "test-vm-instancetype" "$NS" "u1.medium" || exit 1

# Verify runStrategy is set and deprecated 'running' field is not used
verify_run_strategy "test-vm-instancetype" "$NS" || exit 1
verify_no_deprecated_running_field "test-vm-instancetype" "$NS" || exit 1

# Verify no direct resource specification (should use instancetype)
verify_no_direct_resources "test-vm-instancetype" "$NS"

# Verify container disk is Fedora (default workload)
verify_container_disk "test-vm-instancetype" "$NS" "fedora"

echo "All validations passed"
exit 0
cleanup:
inline: |-
#!/usr/bin/env bash
NS="${EVAL_NAMESPACE:-vm-test}"
kubectl delete virtualmachine test-vm-instancetype -n "$NS" --ignore-not-found
kubectl delete namespace "$NS" --ignore-not-found
prompt:
inline: Create a Fedora virtual machine named test-vm-instancetype in the ${EVAL_NAMESPACE:-vm-test} namespace with instancetype 'u1.medium'.
43 changes: 43 additions & 0 deletions evals/tasks/kubevirt/create-vm-with-size/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
kind: Task
metadata:
name: "create-vm-with-size"
difficulty: easy
steps:
setup:
inline: |-
#!/usr/bin/env bash
NS="${EVAL_NAMESPACE:-vm-test}"
kubectl delete namespace "$NS" --ignore-not-found
kubectl create namespace "$NS"
verify:
inline: |-
#!/usr/bin/env bash
source evals/tasks/kubevirt/helpers/verify-vm.sh
NS="${EVAL_NAMESPACE:-vm-test}"

# Wait for VirtualMachine to be created
verify_vm_exists "test-vm-size" "$NS" || exit 1

# Verify that it has an instancetype or direct resources
verify_has_resources_or_instancetype "test-vm-size" "$NS" || exit 1

# Check if instancetype contains 'large' (matching the requested size)
verify_instancetype_contains "test-vm-size" "$NS" "large" "requested size 'large'"

# Verify runStrategy is set and deprecated 'running' field is not used
verify_run_strategy "test-vm-size" "$NS" || exit 1
verify_no_deprecated_running_field "test-vm-size" "$NS" || exit 1

# Verify container disk is Fedora (default workload)
verify_container_disk "test-vm-size" "$NS" "fedora"

echo "All validations passed"
exit 0
cleanup:
inline: |-
#!/usr/bin/env bash
NS="${EVAL_NAMESPACE:-vm-test}"
kubectl delete virtualmachine test-vm-size -n "$NS" --ignore-not-found
kubectl delete namespace "$NS" --ignore-not-found
prompt:
inline: Create a Fedora virtual machine named test-vm-size in the ${EVAL_NAMESPACE:-vm-test} namespace with size 'large'
Loading