mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-21 11:46:37 +00:00
370 lines
9.6 KiB
Markdown
370 lines
9.6 KiB
Markdown
# Hive installation
|
|
|
|
## Dependencies
|
|
|
|
For running on Ubuntu 22.04
|
|
|
|
```bash
|
|
add-apt-repository universe
|
|
apt install nbdkit nbdkit-plugin-dev pkg-config qemu-system qemu-utils qemu-kvm libvirt-daemon-system libvirt-clients libvirt-dev
|
|
```
|
|
|
|
Create hive user
|
|
|
|
```
|
|
adduser --disabled-password hive
|
|
```
|
|
|
|
Add hive to the libvirt group to manage VMs
|
|
|
|
```
|
|
adduser hive libvirt
|
|
```
|
|
|
|
## Build
|
|
|
|
```
|
|
make
|
|
```
|
|
|
|
## Services
|
|
|
|
Start libvirt networking (TODO, requires individual VPC support)
|
|
|
|
```bash
|
|
virsh -c qemu:///system net-start default
|
|
```
|
|
|
|
## Launch
|
|
|
|
```bash
|
|
nbdkit -p 10812 --pidfile /tmp/vb-vol-1.pid ../viperblock/lib/nbdkit-viperblock-plugin.so -v -f size=67108864 volume=vol-2 bucket=predastore region=ap-southeast-2 access_key="X" secret_key="Y" base_dir="/tmp/vb/" host="https://127.0.0.1:8443" cache_size=0
|
|
```
|
|
|
|
## Create AMI template
|
|
|
|
### Step 1
|
|
|
|
Download the selected image
|
|
|
|
```bash
|
|
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2 -O $HOME/debian-12-genericcloud-amd64.qcow2
|
|
```
|
|
|
|
Confirm nbd available in the kernel
|
|
|
|
```bash
|
|
lsmod | grep nbd
|
|
```
|
|
|
|
If missing enable in the kernel
|
|
|
|
```bash
|
|
modprobe nbd
|
|
```
|
|
|
|
Add nbd to be included at boot if missing.
|
|
|
|
```bash
|
|
echo nbd | sudo tee -a /etc/modules
|
|
```
|
|
|
|
Mount the qcow2 image
|
|
|
|
```bash
|
|
sudo qemu-nbd -r --connect=/dev/nbd0 $HOME/debian-12-genericcloud-amd64.qcow2
|
|
```
|
|
|
|
### Step 2
|
|
|
|
Confirm disk attributes
|
|
|
|
```bash
|
|
fdisk -l /dev/nbd0
|
|
```
|
|
|
|
Note a Linux cloud image should be similar to the following:
|
|
|
|
```bash
|
|
Disk /dev/nbd0: 3 GiB, 3221225472 bytes, 6291456 sectors
|
|
Units: sectors of 1 * 512 = 512 bytes
|
|
Sector size (logical/physical): 512 bytes / 512 bytes
|
|
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
|
Disklabel type: gpt
|
|
Disk identifier: 7C03A441-F052-CB42-A148-27D2974B71B0
|
|
|
|
Device Start End Sectors Size Type
|
|
/dev/nbd0p1 262144 6289407 6027264 2.9G Linux root (x86-64)
|
|
/dev/nbd0p14 2048 8191 6144 3M BIOS boot
|
|
/dev/nbd0p15 8192 262143 253952 124M EFI System
|
|
```
|
|
|
|
### Step 3
|
|
|
|
Copy block by block (zero blocks will be skipped), requires root to read the raw /dev/nbd0 device. Confirm the $SIZE attribute from the fdisk output above.
|
|
|
|
Export the following and replace with your ACCESS_KEY & SECRET_KEY defined in `hive/config/predastore/predastore.toml`.
|
|
|
|
```bash
|
|
export VSIZE=3221225472
|
|
export ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
|
|
export SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
|
```
|
|
|
|
Create a temporary ramdisk for performance when creating images, or substitute the location for a higher speed (e.g nvme drive)
|
|
|
|
```bash
|
|
mount -t tmpfs -o size=8G tmpfs /mnt/ramdisk/
|
|
```
|
|
|
|
## Step 4
|
|
|
|
Ensure predastore is currently running
|
|
|
|
```bash
|
|
go run cmd/hive/main.go service predastore --base-path ~/hive/predastore/ --config-path ~/Development/mulga/hive/config/predastore/predastore.toml --tls-cert ~/Development/mulga/hive/config/server.pem --tls-key ~/Development/mulga/hive/config/server.key start
|
|
```
|
|
|
|
## Step 5
|
|
|
|
Define the AMI attributes, see the sample template at `viperblock/tests/import-ami.json`, if using the example `debian-12-genericcloud-amd64.qcow2` the sample template can be used.
|
|
|
|
```json
|
|
{
|
|
"VolumeMetadata": {
|
|
"VolumeID": "",
|
|
"VolumeName": "debian-12.10.0-ami",
|
|
"TenantID": "tenant-001",
|
|
"SizeGiB": 0,
|
|
"State": "available",
|
|
"AvailabilityZone": "ap-southeast-2",
|
|
"AttachedInstance": "",
|
|
"DeviceName": "",
|
|
"VolumeType": "gp3",
|
|
"IOPS": 1000,
|
|
"Tags": null,
|
|
"SnapshotID": "",
|
|
"IsEncrypted": false
|
|
},
|
|
"AMIMetadata": {
|
|
"ImageID": "",
|
|
"Name": "debian-12.10.0",
|
|
"Description": "Debian 12.10.0 minimal cloud image prepared for Hive",
|
|
"Architecture": "arm64",
|
|
"PlatformDetails": "Linux/UNIX",
|
|
"RootDeviceType": "ebs",
|
|
"Virtualization": "hvm",
|
|
"ImageOwnerAlias": "hive",
|
|
"VolumeSizeGiB": 0,
|
|
"Tags": null
|
|
}
|
|
```
|
|
|
|
Import the raw disk as a new AMI
|
|
|
|
```bash
|
|
sudo ../viperblock/bin/vblock -file=/dev/nbd0 -size=$VSIZE -volume=ami-debian-12-genericcloud -bucket=predastore -region=ap-southeast-2 -access_key="$ACCESS_KEY" -secret_key="$SECRET_KEY" -base_dir="/mnt/ramdisk/vbimport" -host="https://127.0.0.1:8443" -metadata=../viperblock/tests/import-ami.json
|
|
```
|
|
|
|
At the end of the import the new AMI ID will be referenced, e.g
|
|
|
|
```json
|
|
time=2025-07-16T12:36:18.016+10:00 level=INFO msg="VB Close, flushing block state to disk"
|
|
time=2025-07-16T12:36:18.016+10:00 level=DEBUG msg="OpenWAL complete, new WAL" file={file:0xc00009c780}
|
|
time=2025-07-16T12:36:18.017+10:00 level=DEBUG msg="Saving Close state to" path=/mnt/ramdisk/vbimport/ami-185c47c7b6d31bba9
|
|
```
|
|
|
|
Unmount the temp filesystem
|
|
|
|
```bash
|
|
umount /mnt/ramdisk/
|
|
```
|
|
|
|
## Start services
|
|
|
|
### NATS
|
|
|
|
An embedded NATS server provides messaging between components of Hive and is a requirement.
|
|
|
|
```
|
|
go run cmd/hive/main.go service nats start --debug
|
|
```
|
|
|
|
### Hive daemon
|
|
|
|
The background Hive daemon is a core service which accepts requests to provision services such as the AWS SDK/CLI.
|
|
|
|
```
|
|
go run cmd/hive/main.go --config config/hive.toml daemon
|
|
```
|
|
|
|
## Provision instance
|
|
|
|
Once the required services are running, use the examples provided below to provision services.
|
|
|
|
### EC2 instance
|
|
|
|
### SSH setup
|
|
|
|
The first step is to provide a public SSH key which will be used by `cloud-init` when a new EC2 (Linux) instance is launched.
|
|
|
|
Upload your public-key to the predastore S3 repository using the AWS CLI tool. Confirm your credentials are correctly defined in `~/.aws/credentials` that match the predastore configuration file `config/predastore/predastore.toml` and the region defined.
|
|
|
|
```
|
|
cat ~/.aws/credentials
|
|
[predastore]
|
|
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
|
|
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
|
```
|
|
|
|
Confirm access is working and the previous AMI is visible:
|
|
|
|
```
|
|
AWS_REGION=ap-southeast-2 aws --no-verify-ssl --endpoint-url https://localhost:844
|
|
3/ s3 ls s3://predastore/
|
|
```
|
|
|
|
Output:
|
|
|
|
```
|
|
PRE ami-185c47c7b6d31bba9/
|
|
```
|
|
|
|
Upload SSH key
|
|
|
|
```
|
|
AWS_REGION=ap-southeast-2 aws --no-verify-ssl --endpoint-url https://localhost:8443/ s3 cp ~/.ssh/id_rsa.pub s3://predastore/ssh/test-keypair.pub
|
|
upload: ../../../.ssh/id_rsa.pub to s3://predastore/ssh/test-keypair.pub
|
|
```
|
|
|
|
### Launch instance
|
|
|
|
To launch a sample EC2 instance edit `tests/ec2.json` and replace the AMI ID from the previous step (e.g ami-185c47c7b6d31bba9)
|
|
|
|
tests/ec2.json:
|
|
|
|
```
|
|
{
|
|
"Action": "RunInstances",
|
|
"ImageId": "ami-185c47c7b6d31bba9",
|
|
"InstanceType": "t3.micro",
|
|
"KeyName": "test-keypair.pub",
|
|
"SecurityGroups": [
|
|
"MySecurityGroup"
|
|
],
|
|
"SubnetId": "subnet-6e7f829e",
|
|
"MaxCount": 1,
|
|
"MinCount": 1,
|
|
"Version": "2016-11-15"
|
|
}
|
|
```
|
|
|
|
Publish the EC2 request using the NATS cli tool.
|
|
|
|
```
|
|
cat tests/ec2.json | nats --trace pub ec2.launch
|
|
```
|
|
|
|
# Launching services
|
|
|
|
### NATS
|
|
|
|
```
|
|
go run cmd/hive/main.go service nats start
|
|
```
|
|
|
|
### Predastore
|
|
|
|
```
|
|
go run cmd/hive/main.go service predastore --base-path ~/hive/predastore/ --config-path ~/Development/mulga/hive/config/predastore/predastore.toml --tls-cert ~/Development/mulga/hive/config/server.pem --tls-key ~/Development/mulga/hive/config/server.key --debug start
|
|
```
|
|
|
|
### Viperblock
|
|
|
|
```
|
|
go run cmd/hive/main.go service viperblock start --nats-host 0.0.0.0:4222 --access-key "AKIAIOSFODNN7EXAMPLE" --secret-key "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" --base-dir /mnt/ramdisk/ --plugin-path ~/Development/mulga/viperblock/lib/nbdkit-viperblock-plugin.so
|
|
```
|
|
|
|
### Hive (Control Plane)
|
|
|
|
```
|
|
go run cmd/hive/main.go --config config/hive.toml --base-dir /mnt/ramdisk/ daemon
|
|
```
|
|
|
|
# Example events
|
|
|
|
### Mount volume
|
|
|
|
```
|
|
|
|
```
|
|
|
|
### Unmount volume
|
|
|
|
### Launch EC2
|
|
|
|
```
|
|
nats req ec2.launch '{"Action":"RunInstances","ImageId":"ami-185c47c7b6d31bba9","InstanceType":"t3.micro","KeyName":"test-keypair.pub","SecurityGroups":["MySecurityGroup"],"SubnetId":"subnet-6e7f829e","MaxCount":1,"MinCount":1,"Version":"2016-11-15"}'
|
|
```
|
|
|
|
### Describe instance
|
|
|
|
```
|
|
nats req --reply-timeout=5s ec2.describe.i-ebaf0fd46cad14c85 '{ "InstanceID": "i-ebaf0fd46cad14c85" }'
|
|
```
|
|
|
|
### Start instance
|
|
|
|
```
|
|
nats req ec2.startinstances '{"InstanceID": "i-f38ac0490f1683650"}'
|
|
```
|
|
|
|
|
|
## QMP commands
|
|
|
|
### Powerdown
|
|
|
|
This event is used internally be Hive when the daemon receives a SIGINT, SIGTERM, SIGHUP signal to safely powerdown an instance, or when the hardware node is rebooted.
|
|
|
|
```
|
|
nats req --reply-timeout=5s ec2.cmd.i-ebaf0fd46cad14c85 '{ "id": "i-ebaf0fd46cad14c85", "command": { "execute": "system_powerdown", "arguments": {} } }'
|
|
```
|
|
|
|
### Terminate instance
|
|
|
|
This event is for a user initiated instance termination. Note the Attributes, to flag to the Hive daemon not to start the instance again if the daemon or hardware node is restarted.
|
|
|
|
```
|
|
nats req --reply-timeout=5s ec2.cmd.i-f38ac0490f1683650 '{ "id": "i-f38ac0490f1683650", "attributes": { "stop_instance": true }, "command": { "execute": "system_powerdown", "arguments": {} } }'
|
|
```
|
|
|
|
### Stop VM
|
|
|
|
```
|
|
nats req --reply-timeout=5s ec2.cmd.i-ebaf0fd46cad14c85 '{ "id": "i-ebaf0fd46cad14c85", "command": { "execute": "stop", "arguments": {} } }'
|
|
```
|
|
|
|
### Resume VM
|
|
|
|
```
|
|
nats req --reply-timeout=5s ec2.cmd.i-ebaf0fd46cad14c85 '{ "id": "i-ebaf0fd46cad14c85", "command": { "execute": "cont", "arguments": {} } }'
|
|
```
|
|
|
|
### Restart
|
|
|
|
```
|
|
nats req --reply-timeout=5s ec2.cmd.i-ebaf0fd46cad14c85 '{ "id": "i-ebaf0fd46cad14c85", "command": { "execute": "system_reset", "arguments": {} } }'
|
|
```
|
|
|
|
### Query status
|
|
|
|
```
|
|
nats req --reply-timeout=5s ec2.cmd.i-ebaf0fd46cad14c85 '{ "id": "i-ebaf0fd46cad14c85", "command": { "execute": "query-status", "arguments": {} } }'
|
|
```
|
|
|
|
### Query devices
|
|
|
|
```
|
|
nats req --reply-timeout=5s ec2.cmd.i-ebaf0fd46cad14c85 '{ "id": "i-ebaf0fd46cad14c85", "command": { "execute": "query-device", "arguments": {} } }'
|
|
```
|