Skip to content
Permalink
Browse files

update README and add example statechange scripts for exporting with …

…docker or running debootstrap
  • Loading branch information...
jacobgorm committed Mar 12, 2019
1 parent 2570d5d commit 5e4a67657e2831eb316d3ce82c4ac0d300e37b91
Showing with 121 additions and 18 deletions.
  1. +29 −18 README.md
  2. +39 −0 dockerexport.sh
  3. +28 −0 statechange-debootstrap.sh
  4. +25 −0 statechange-docker.sh
@@ -1,6 +1,6 @@
# Welcome to Mindcastle.io

This repository contains the Mindcastle.io (formerly oneroot) distributed block
This repository contains the Mindcastle.io (formerly mindcastle) distributed block
device, whose aim is to eventually become the 'git for storage'. It is
currently mostly useful for local use, and for creating locally writable mounts that
can be exported simply by placing the chunked files it creates on an HTTP
@@ -42,30 +42,34 @@ so feel free to use that instead if you prefer.

## Running

You can run mindcastle's NBD backend with (must be root, prefix with sudo if that is your thing):
You can run mindcastle's NBD backend with (must be root, prefix with sudo as necessary):

```bash
modprobe nbd
oneroot mydisk.swap ./statechange.sh
build/mindcastle mydisk.swap ./statechange.sh
```

oneroot implements a user-space block device on top of Linux' nbd module. The
mindcastle implements a user-space block device on top of Linux' nbd module. The
mydisk.swap file is a tiny meta-data text file that will be created if not
there already. The actual disk contents will go inside a directory called
swapdata-UUID, where UUID gets randomly generated. As long as oneroot is
swapdata-UUID, where UUID gets randomly generated. As long as mindcastle is
running, you now have an empty block device that you can format and use
as any other block device. (To not have to do this manually each time, the
script "stagechange.sh" takes care to do this automically, you can edit the
script "statechange.sh" takes care to do this automically, you can edit the
script to choose the type of filesystem or perform automated tasks on, e.g,
automatically syncing files to the file system and then unmounting it when done.)

If you peek inside swapdata-UUID, you will see a lot of regularly-sized files
(currently the chunking size is set to 1MiB) with some insanely long file names.
The file names are derived from the sha512 hashes of the file contents, as you
can verify by running the 'sha512' tool against one of them (the hashes get truncated
at 256 bits when used for filenames). If you wanted to publish it on an HTTP server, say running out of /srv/http, you would do
something line this (assuming the HTTP server serves files out /srv/http and there is a http
user on the system that the server is running as):
Please note the it needs to be resolvable in your $PATH, which is why it is
shown prefixed with ./ above.

If you peek inside swapdata-UUID, you will see a lot of regularly-sized files.
The file names are derived from the sha512 hashes (but shortened to 256 bits
for your sanity) of the file contents, as you can verify by running the
'sha512' tool against one of them (the hashes get truncated at 256 bits when
used for filenames). If you wanted to publish it on an HTTP server, say running
out of /srv/http, you would do something line this (assuming the HTTP server
serves files out /srv/http and there is a http user on the system that the
server is running as):

```bash
cp -r swapdata-UUID /srv/http
@@ -91,19 +95,26 @@ server acting as the storage backend.
Then, on the client machine, you could connect the block device with:

```bash
oneroot mydisk.swap ./stagechange.sh
build/mindcastle mydisk.swap ./statechange.sh
```

Where "./stagechange.sh" is the path to the default stagechange script, which will
Where "./statechange.sh" is the path to the default statechange script, which will
format the volume if necessary, and mount and later unmount it under
/tmp/mnt-UUID. The script interacts with the oneroot process using signals,
/tmp/mnt-UUID. The script interacts with the mindcastle process using signals,
and the user can do this too. For example, to trigger a clean unmount and
shutdown, just do a

```bash
kill -1 PID
```

Where PID is that of the first oneroot process, you should see this logged
by the script on startup. See the stagechange.sh script comments for more
Where PID is that of the first mindcastle process, you should see this logged
by the script on startup. See the statechange.sh script comments for more
details.

## Using with docker

We normally use mindcastle as for broadcasting VMs or container images authored
using docker. Please see the example script dockerexport.sh and the
statechange-docker.sh script that we use as a template when building and
exporting a docker image to mindcastle.
@@ -0,0 +1,39 @@
#!/bin/bash

# example script that builds a docker container and exports its contents
# to a mindcastle block device, and then exports the contents of that block
# device to an object store like S3.

sudo echo building docker container || exit 1

SWAP=tmp.swap

sudo rm -rf tmp ; mkdir tmp # dir that we export container to

echo building with revisions $ONEROOTREVISION
docker rm mycontainer
docker build -t mycontainer || exit 1
echo run docker container to ready for export...
docker run --name mycontainer mycontainer /bin/true || exit 1
echo export docker container to tmp dir...
docker export mycontainer | (cd tmp; sudo tar x)
echo rm docker container
docker rm mycontainer

# now start oneroot to make rsync from tmp happen

sudo $HOME/dev/oneroot/build/oneroot $SWAP ./statechange-docker.sh || exit 1

sudo rm -rf tmp

# source the .swap file to get the UUID
source ./$SWAP || exit 1

# create mycontainer.swap with a fallback link to cloud location
SERVER=swapdata-$uuid.s3-eu-west-1.amazonaws.com
cat $SWAP >target.swap
echo cache=cache >>target.swap
echo fallback=http://$SERVER >>mycontainer.swap

# finally copy the new state to the object store in the cloud
rclone -v sync swapdata-$uuid/ s3:swapdata-$uuid
@@ -0,0 +1,28 @@
#!/bin/sh

# example script for creating a VM or container image with debootstrap
#
# run with:
#
# $ sudo ./build/mindcastle debian.swap ./statechange-debootstrap.sh

echo $0 PID=$PID UUID=$UUID $1
MNT=/tmp/mnt-$UUID

case "$1" in

create)
mkfs.xfs $DEVICE && exec $0 open
;;

open)
(mkdir -p $MNT && mount -osync $DEVICE $MNT) || (rm -rf $MNT; kill -2 $PID)
debootstrap stable $MNT
kill -1 $PID
;;

close)
umount $MNT && rm -rf $MNT && kill -2 $PID
;;

esac
@@ -0,0 +1,25 @@
#!/bin/sh

MNT=/tmp/mnt-$UUID

case "$1" in

create)
mkfs.xfs $DEVICE && exec $0 open
;;

open)
mkfs.xfs $DEVICE 2> /dev/null # will fail if already formatted
mkdir -p $MNT &&
mount -osync $DEVICE $MNT &&
rsync --chown=root:root -av --delete tmp/ $MNT
kill -1 $PID
;;

close)
echo unmounting $MNT
umount -f $MNT && rm -rf $MNT
kill -2 $PID
;;

esac

0 comments on commit 5e4a676

Please sign in to comment.
You can’t perform that action at this time.