Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jpetazzo committed Aug 31, 2018
0 parents commit 7a1bab8
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
images/
vms/
42 changes: 42 additions & 0 deletions README.md
@@ -0,0 +1,42 @@
# Littleboxes

This is a collection of scripts (well, just one script for now!) to
manage local VMs running with QEMU/KVM. It is purely for educational
purposes.


## Prerequirements

You need the following:
- QEMU
- VDE
- cloud-localds (ArchLinux package: "cloud-utils")
- tmux


## How to use

```bash
./lbx.sh pull xenial
./lbx.sh create xenial node1
./lbx.sh create xenial node2
./lbx.sh start node1
./lbx.sh start node2
tmux attach
```

Use `Ctrl-B X` (where `X` is a number) to switch between tmux tabs.
Login and password are `ubuntu`. VMs should have outbound network
access. The VMs are also connected by a private network (using VDE)
but it's not configured (yet).


## TODO

- find a way to setup the internal network
- some cloud init wizardry?
- also, pre-allocate addresses, or DHCP appliance?
- find a way to SSH to all machines
- perhaps with a vde_plug to tap into the internal network
- or a network appliance

7 changes: 7 additions & 0 deletions cloud-init
@@ -0,0 +1,7 @@
#cloud-config
password: ubuntu
chpasswd: { expire: False }
ssh_pwauth: True
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDxLXAXB3CUztORPd+SCEcxhSGakSqecCgtCQTK3owuOKnG9LAYsXFDc7DLGoWzhnYeU9fVkKuMh6aDXYCHJmjSyK5V7f+VVxrH/6kf2VrIK+bGglHbPxNVLS1/UsSEzdZdP0vFwoBoGjAFNFEcn0NXKAvtNlMsyakvjfrpuPIFrb7xkrZHhvezNKrG3Sx6lQ2RaSFFGJSTPOWQg/q8DsCv0D1T7RaR1oHrrb6KKQAWjGYoU75/zNN6x7nD/ITQe7JGNPS3JbqXqXj7WtM4Wm0FHF5CthEKecbyxCFGxhpNBwXN2GzNkItQkeans+pn6/g6lstWIT/ugddoxW3CvQt1 /home/jp/.ssh/id_rsa

3 changes: 3 additions & 0 deletions images/README
@@ -0,0 +1,3 @@
This directory will contain images (templates for VMs).

Each image is represented by a directory containing a file named "hda".
136 changes: 136 additions & 0 deletions lbx.sh
@@ -0,0 +1,136 @@
#!/bin/bash
#set -ex

_help="$(basename "$0") - a tool to manipulate little boxes"
_cmd () {
COMMAND=$1
HELP=$2
_help=$(printf "%s\n%-10s\t%s" "$_help" "$COMMAND" "$HELP")
}

_cmd_ () {
echo "$_help"
}

_check_image () {
if [ ! -n "$1" ]; then
echo "Specify image name"
exit 1
fi
if [ "$2" = "exists" ]; then
if [ ! -d images/$1 ]; then
echo "Image $1 does not exist"
exit 1
fi
fi
}

_check_vm () {
if [ ! -n "$1" ]; then
echo "Specify VM name"
exit 1
fi
if [ "$2" = "exists" ]; then
if [ ! -d vms/$1 ]; then
echo "VM $1 does not exist"
exit 1
fi
fi
}

_cmd pull "Pull a VM image"
_cmd_pull () {
IMAGE=$1
_check_image $IMAGE
mkdir images/$IMAGE
wget https://cloud-images.ubuntu.com/$IMAGE/current/$IMAGE-server-cloudimg-amd64-disk1.img -O images/$IMAGE/hda
}

_cmd create "Create a VM from an image"
_cmd_create () {
IMAGE=$1
VM=$2
_check_image $IMAGE exists
_check_vm $VM
mkdir vms/$VM
qemu-img create -f qcow2 -b ../../images/$IMAGE/hda vms/$VM/hda
cloud-localds --disk-format qcow2 --hostname $VM vms/$VM/hdb cloud-init
_cmd_config $VM
}

_cmd config "(Re)configure a VM"
_cmd_config () {
VM=$1
_check_vm "$VM" exists
MAC=$(printf "52:54:00:%02x:%02x:%02x" $(($RANDOM%256)) $(($RANDOM%256)) $(($RANDOM%256)))
cat >vms/$VM/run.sh <<EOF
#extra=,hostfwd=tcp:127.0.0.1:22001-:22
qemu-system-x86_64 -m 1024 -enable-kvm \
-nographic \
-pidfile vms/$VM/pid \
-hda vms/$VM/hda -hdb vms/$VM/hdb \
-device e1000,netdev=n01 \
-netdev user,id=n01\$extra \
-device e1000,netdev=n02,mac=$MAC \
-netdev vde,id=n02
EOF
}

_cmd vde "Make sure that VDE is running"
_cmd_vde () {
if [ ! -S /tmp/vde.ctl/ctl ]; then
vde_switch -d
fi
}

_cmd start "Start a VM"
_cmd_start () {
VM=$1
_check_vm "$VM" exists
if [ -f vms/$VM/pid ]; then
PID=$(cat vms/$VM/pid)
if [ -d /proc/$PID ]; then
echo "pid file exists and process exists"
echo "the VM is already running?"
exit 1
fi
echo "found pid file but process doesn't exist"
rm vms/$VM/pid
fi
_cmd_vde
tmux has-session || tmux new-session -d
tmux new-window -d -n $VM sh vms/$VM/run.sh
echo "VM started"
}

_cmd stop "Stop a VM"
_cmd_stop () {
VM=$1
_check_vm "$VM" exists
if [ ! -f vms/$VM/pid ]; then
echo "pid file not found"
exit 1
fi
PID=$(cat vms/$VM/pid)
if [ ! -d /proc/$PID ]; then
echo "process doesn't seem to be running"
exit 1
fi
kill $PID
echo "Sent signal to stop VM"
}

_cmd lsi "List images"
_cmd_lsi () {
ls images
}

_cmd lsv "List VMs"
_cmd_lsv () {
ls vms
}

cmd=$1
fun=_cmd_$cmd
shift
$fun "$@"
6 changes: 6 additions & 0 deletions vms/README
@@ -0,0 +1,6 @@
This directory will contain VMs (ready to run).

Each VM is represented by a directory containing:
- a file named "hda" (the boot disk)
- a file named "hdb" (containing a cloud init payload)
- a file named "run.sh" (a script starting the VM)

0 comments on commit 7a1bab8

Please sign in to comment.