Skip to content
Open
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
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ NAME STATUS ROLES AGE VERSION
opsv Ready control-plane,master 4h58m v1.29.6+k3s1
```

## (Optional) Add block storage rook

```
multipass exec opsv -- bash -c 'export KUBECONFIG=/home/ubuntu/.kube/config && /home/ubuntu/add-rook'

```

## (Optional) Add block storage longhorn

```
multipass exec opsv -- bash -c 'export KUBECONFIG=/home/ubuntu/.kube/config && /home/ubuntu/add-longhorn'

```

# Development Environment Overview

If you only want to test OpenServerless, stop here. You should have a working environment.
Expand Down
118 changes: 116 additions & 2 deletions cloud-init.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,121 @@ write_files:
bash direnv-init.sh
# TODO add a .git-hooks directory with hooks
#git config core.hooksPath .git-hooks


- path: /home/ubuntu/add-rook
permissions: '0755'
defer: true
owner: ubuntu:ubuntu
content: |
#!/bin/bash
set -e

ROOK_VERSION="v1.14.6"
RAW_BASE="https://raw.githubusercontent.com/rook/rook/${ROOK_VERSION}/deploy/examples"

echo "📦 Installing Rook ${ROOK_VERSION}"
echo "📄 Applying CRDs and operator..."
kubectl apply -f ${RAW_BASE}/crds.yaml
kubectl apply -f ${RAW_BASE}/common.yaml
kubectl apply -f ${RAW_BASE}/operator.yaml
sleep 10

if ! command -v yq >/dev/null 2>&1; then
echo "📥 Installing yq..."
mkdir -p /home/ubuntu/bin
curl -sL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -o /home/ubuntu/bin/yq
chmod +x /home/ubuntu/bin/yq
export PATH=/home/ubuntu/bin:$PATH
else
echo "✅ yq already installed."
fi

echo "🛠️ Patching and applying Ceph cluster for single-node setup..."
curl -sL ${RAW_BASE}/cluster.yaml | \
yq e '.spec.mon.count = 1 | .spec.mon.allowMultiplePerNode = true' - | \
kubectl apply -f -
sleep 30

echo "📄 Applying Ceph client..."
kubectl apply -f ${RAW_BASE}/ceph-client.yaml

echo "🔍 Waiting for Rook to be Ready..."
for i in {1..90}; do
status=$(kubectl -n rook-ceph get cephcluster rook-ceph -o jsonpath='{.status.phase}' 2>/dev/null || echo "notfound")
echo "⏳ Attempt $i: Rook status = $status"
if [[ "$status" == "Ready" ]]; then
echo "✅ Rook is healthy!"
break
fi
sleep 15
done

if [[ "$status" != "Ready" ]]; then
echo "❌ Timeout waiting for Rook to become healthy."
exit 1
fi

echo "📄 Installing VolumeSnapshot CRDs..."
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v6.3.3/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v6.3.3/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v6.3.3/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml

echo "🧹 Re-creating rook-ceph-block StorageClass..."
kubectl delete storageclass rook-ceph-block --ignore-not-found=true

cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: rook-ceph.rbd.csi.ceph.com
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
parameters:
clusterID: rook-ceph
pool: replicapool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
csi.storage.k8s.io/fstype: ext4
EOF

echo "✅ Rook installed and configured with default StorageClass rook-ceph-block."

- path: /home/ubuntu/add-longhorn
permissions: '0755'
defer: true
owner: ubuntu:ubuntu
content: |
#!/bin/bash
set -e

LONGHORN_VERSION="v1.4.1"

echo "📦 Installing Longhorn ${LONGHORN_VERSION}"
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/${LONGHORN_VERSION}/deploy/longhorn.yaml

for i in {1..90}; do
ready=$(kubectl -n longhorn-system get pods -l app=longhorn-manager -o jsonpath='{.items[*].status.containerStatuses[0].ready}' | grep -o true | wc -l)
total=$(kubectl -n longhorn-system get pods -l app=longhorn-manager --no-headers | wc -l)
echo "⏳ Attempt $i: $ready/$total pods ready"
[[ "$ready" == "$total" && "$total" -gt 0 ]] && echo "✅ Longhorn Ready" && break
sleep 15
done

echo "📦 Trying to set Longhorn as default storage class ..."
if kubectl get storageclass longhorn >/dev/null 2>&1; then
kubectl annotate storageclass longhorn storageclass.kubernetes.io/is-default-class=true --overwrite || true
fi

runcmd:
- |
cd /home/ubuntu
Expand All @@ -100,4 +214,4 @@ runcmd:
curl -sL https://raw.githubusercontent.com/sciabarracom/openserverless/refs/heads/main/bash_aliases -o ".bash_aliases"
echo 'source $HOME/.z.sh' >> .bashrc
chown ubuntu:ubuntu .z.sh .bashrc .bash_aliases
echo -e '#!/bin/bash\n/etc/cloud-init.sh 2>&1 >/tmp/cloud-init.log\n' | at now
echo -e '#!/bin/bash\n/etc/cloud-init.sh 2>&1 >/tmp/cloud-init.log\n' | at now