# Cloud Hypervisor SAL - Quick Start Guide

Get started with the Cloud Hypervisor Service Abstraction Layer in minutes.

## Prerequisites

1. **Cloud Hypervisor** installed at `/usr/local/bin/cloud-hypervisor`
2. **Rust toolchain** (1.70+)
3. **Ubuntu cloud image** and VM files in `~/cloud/`
4. **sudo access** for network configuration

## Step 1: Prepare VM Files

Create the VM files directory:
```bash
mkdir -p ~/cloud
cd ~/cloud
```

Download Ubuntu cloud image:
```bash
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
```

Convert and resize:
```bash
qemu-img convert -f qcow2 -O raw jammy-server-cloudimg-amd64.img ubuntu.raw
qemu-img resize ubuntu.raw 10G
```

Extract kernel and initramfs:
```bash
sudo modprobe nbd max_part=8
sudo qemu-nbd --connect=/dev/nbd0 jammy-server-cloudimg-amd64.img
sudo mount /dev/nbd0p1 /mnt
sudo cp /mnt/boot/vmlinuz-* ~/cloud/vmlinuz-cloud
sudo cp /mnt/boot/initrd.img-* ~/cloud/initrd-cloud.img
sudo umount /mnt
sudo qemu-nbd --disconnect /dev/nbd0
sudo chown $USER:$USER ~/cloud/vmlinuz-cloud ~/cloud/initrd-cloud.img
```

Expand the filesystem:
```bash
sudo losetup -fP ubuntu.raw
LOOP_DEV=$(sudo losetup -l | grep ubuntu.raw | awk '{print $1}')
sudo growpart $LOOP_DEV 1
sudo e2fsck -f ${LOOP_DEV}p1
sudo resize2fs ${LOOP_DEV}p1
sudo losetup -d $LOOP_DEV
```

## Step 2: Create Cloud-Init Configuration

Create `~/cloud/user-data-network.yaml`:
```yaml
#cloud-config
hostname: ubuntu-vm
users:
  - name: ubuntu
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-rsa YOUR_SSH_KEY_HERE
    lock_passwd: false
    passwd: $6$rounds=4096$saltsalt$hashed_password

ssh_pwauth: true
chpasswd:
  list: |
    ubuntu:password123
  expire: false

packages:
  - curl
  - wget
  - net-tools
  - iputils-ping
  - openssh-server

runcmd:
  - systemctl enable ssh
  - systemctl start ssh
```

Create `~/cloud/network-config-static.yaml`:
```yaml
version: 2
ethernets:
  eth0:
    addresses:
      - 192.168.100.10/24
    gateway4: 192.168.100.1
    nameservers:
      addresses:
        - 8.8.8.8
        - 8.8.4.4
```

Create `~/cloud/meta-data.yaml`:
```yaml
instance-id: ubuntu-vm-001
local-hostname: ubuntu-vm
```

Generate cloud-init ISO:
```bash
cloud-localds ~/cloud/cloud-init-network.iso \
  ~/cloud/user-data-network.yaml \
  --network-config=~/cloud/network-config-static.yaml \
  ~/cloud/meta-data.yaml
```

## Step 3: Setup Network

Create `~/cloud/setup_tap_preconfigured.sh`:
```bash
#!/bin/bash
set -e

echo "Cleaning up old interfaces..."
sudo ip link set tap-ch0 down 2>/dev/null || true
sudo ip link delete tap-ch0 2>/dev/null || true
sudo ip link set virbr0 down 2>/dev/null || true
sudo ip link delete virbr0 2>/dev/null || true

echo "Creating bridge virbr0..."
sudo ip link add virbr0 type bridge
sudo ip addr add 192.168.100.1/24 dev virbr0
sudo ip link set virbr0 up

echo "Creating and pre-configuring TAP interface..."
sudo ip tuntap add tap-ch0 mode tap
sudo ip link set tap-ch0 master virbr0
sudo ip link set tap-ch0 up

echo "Enabling IP forwarding..."
sudo sysctl -w net.ipv4.ip_forward=1

DEFAULT_IF=$(ip route | grep default | awk '{print $5}' | head -1)
echo "Default interface: $DEFAULT_IF"

echo "Setting up NAT and forwarding..."
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o $DEFAULT_IF -j MASQUERADE
sudo iptables -A FORWARD -i virbr0 -o $DEFAULT_IF -j ACCEPT
sudo iptables -A FORWARD -i $DEFAULT_IF -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT

echo "Setting up SSH port forwarding (2222 -> VM:22)..."
sudo iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 192.168.100.10:22
sudo iptables -A FORWARD -p tcp -d 192.168.100.10 --dport 22 -j ACCEPT

echo "✅ Network setup complete!"
```

Make it executable and run:
```bash
chmod +x ~/cloud/setup_tap_preconfigured.sh
sudo ~/cloud/setup_tap_preconfigured.sh
```

## Step 4: Build and Run

Build the virt package:
```bash
cd packages/virt
cargo build --release
```

Run the example VM (all configuration is in the script):
```bash
sudo herodo examples/rhai/cloudhv/start_vm.rhai
```

## Step 5: Access Your VM

Wait for the VM to boot (~60 seconds), then:

**SSH Access:**
```bash
ssh -p 2222 ubuntu@localhost
# Password: password123
```

**API Access:**
```bash
# Get VM info
sudo curl --unix-socket /tmp/ch-vm.sock http://localhost/api/v1/vm.info | jq .

# Get VM state
sudo curl --unix-socket /tmp/ch-vm.sock http://localhost/api/v1/vm.info | jq -r '.state'
```

## Next Steps

- Explore the [examples](examples/README.md) directory
- Read the [API documentation](README.md#api-reference)
- Create custom Rhai scripts for your use case
- Check out [API_EXAMPLES.md](~/cloud/API_EXAMPLES.md) for advanced API usage

## Troubleshooting

**Build errors:**
```bash
cargo clean
cargo build --release
```

**Network issues:**
```bash
# Re-run network setup
sudo ~/cloud/setup_tap_preconfigured.sh

# Check interfaces
ip link show tap-ch0
ip link show virbr0
```

**VM not booting:**
```bash
# Check logs
sudo journalctl -f | grep cloud-hypervisor

# Verify files exist
ls -lh ~/cloud/vmlinuz-cloud ~/cloud/initrd-cloud.img ~/cloud/ubuntu.raw
```

**Permission errors:**
```bash
# Grant capabilities to Cloud Hypervisor
sudo setcap cap_net_admin+ep /usr/local/bin/cloud-hypervisor
```

For more help, see the main [README](README.md) or open an issue.
