Suspend and Resume shell scripts for Digital Ocean Droplet

タグ: DigitalOcean  

Yes. Vagrant is useful with Digital Ocean Droplet. I agree. But I wanted more simple commands to save/store disk environments.

And I found tugboat command. It was amazing useful, however still I wanted to use more simple way to suspend/resume disk.

So, I made suspend/resume bash shell scripts. (Sorry, they have Japanese comments. But also English, so you can read. ;) )

(And Sorry again for junky My English. If you found something funny, just laugh away! :D :D )

How to use

Good morning. This is the time to continue last night development on droplet...

$> resume (or your shell command file name.)

And you will start today's development...

Then, at night, you feel tired and sleepy, maybe it is good time to suspend your development now.

$> suspend (or your shell command file name.)

Sometime, you must clean up snapshots. Maybe you don't need to keep extra older snapshots. So...

$> cleanup (or your shell command file name.)

Why?

I used a droplet to 'make' some program or generate API documents. It took long time, so set up them, then 'Go!'. I didn't keep my local machine on. Take a walk, or do some daily tasks, when finished them, backed into my machine. And retrieved a result from droplet.

Ya, droplet is fast with SSD. But I don't want every time 'provisioning' and set up when kick up droplet. I just want to use previous disk environments again.

So, we can take snapshot! But you don't want it because spend extra money? Yes and No. Snapshots is achieved disk environment, and count for every GB, however, it doesn’t start to count. It is free right now! So why don't use it?

To take your snapshot, you must 'halt' droplet, then do it. And you must 'destroy' your droplet to stop accounting. The 'tugboat' commands make this easy from command line, but I don't want to repeat multiple commands every time. So I made some bash scripts. DRY up them !

Installing...just copy & paste!

They are simple bash scripts. So make new file, open it by editor, copy & paste, save it, and use magic like 'chmod a+x` for it and move to somewhere under execution paths.

Set up

Open three scripts you have installed. And change top of codes for you.

tugboat command path
tugboat='tugboat'

If you install tugboat command on directory where specified as execution paths, so no needed to change. Otherwise, put full path to 'tugboat' command.

Droplet name
droplet='MyDroplet'

This is a name to put for droplet. Freely change it.

Snapshot name
snapshot='MySnapshot'

This is a snapshot name to save your disk environments of a droplet.

Number of snapshot
remain='1'

This is the remaining snapshot number when clean up. (For cleanup script only.)

Run scripts

Now you can make a droplet manually by using above droplet name, and set up environment.

Then run your suspend script. It will make a snapshot from droplet. Then delete droplet automatically.

When you want re-start, run resume script. It generate droplet from snapshot that kept last your disk. Then connect it with SSH. Normally, droplet size will be depended by tugboat's configuration file. If you want to change droplet size temporary, use --size option with the script. You can select droplet size.

The suspend script will make same named snapshot every time. So you need clean up them sometime. Run cleanup script, then old snapshots will be deleted without the latest ones you specified number of them.

(Tips! If you don't want to make multiple snapshot, so you can hit API directly by using cURL to overwrite specific snapshot. Unfortunately, tugboat don't support it right now.)

Here are scripts!

There are three scripts. I'm still modifying them, so keep the rights, however you can change and use freely.

Resume Script
#!/bin/bash

# Copyright by Hirohisa Kawase

# Specify path to your tugboat command if needed.
# tugboatコマンドのパスを必要ならば、指定して下さい。
tugboat='tugboat'

# Specify Droplet name to make snapshot.
# 保存するドロップレットの名前を指定して下さい。
droplet='MyDroplet'

# Specify snapshot name.
# スナップショット名を指定して下さい。
snapshot='MySnapshot'


# Make temporary file name
# 一時ファイル名生成

tempfile=`mktemp`


# Display size menu.
# サイズメニューの表示

if [ "${1}" = "--size" ]
then

    PS3="Select size, or q)uit > "

    # Get droplet sizes.
    # サイズ取得

    $tugboat size > $tempfile

    awkcommand="{ match(\$0, /(.+) \(id: /, mt); print mt[1]}"
    sizes=`awk -e "$awkcommand" $tempfile`

    select item in $sizes
    do
        if [ "${REPLY}" = "q" ]
        then
            exit 0
        fi

    if [ -z "$item" ]
    then
        continue
    fi

    echo $item

    # Make -s option for create command.
    # 作成コマンドのため、-sオプションを作成する

    awkcommand="{ match(\$0, /${item} \(id: (.+)\)/, mt); print mt[1]}"
    size=`awk -e "$awkcommand" $tempfile`
        sizeoption="-s ${size}"

    break
    done

    # Wait three seconds for missed selection.
    # サイズを間違えた時のために、3秒待つ。

    sleep 3
fi


# Get snapshots.
# スナップショットイメージの取得

$tugboat images > $tempfile
cat $tempfile

# Get latest snapshot image.
# 最後に作成されたスナップショットイメージの取得

awkcommand="/^$snapshot \(id: / { match(\$0, /id: (.+), /, mt); print mt[1] }"
latestsnapshot=`awk -e "$awkcommand" $tempfile | sort -r | head -n 1`

echo $latestsnapshot

if [ -z $latestsnapshot ]
then
    echo Can\'t find droplet by named \'$droplet\' 1>&2
    exit 1
fi

# Create a droplet with latest snapshot image.
# 最後に作成されたスナップショットから、ドロップレットを作成する。

$tugboat create $droplet -i $latestsnapshot $sizeoption

# Get droplets information
# 起動しているドロップレットの情報取得

$tugboat droplets > $tempfile

# Get latest droplet id.
# 最後に作成されたドロップレットの取得

awkcommand="/^$droplet \(ip: / { match(\$0, /id: (.+)\)/, mt); print mt[1] }"
latestdroplet=`awk -e "$awkcommand" $tempfile | sort -r | head -n 1`

# Wait the droplet has made just before, to be active.
# 起動されたばかりドロプレットが、activeになるのを待つ。

$tugboat wait $droplet -i $latestdroplet -s active

# Wait a more while, then connect with SSH.
# (Because of hangup the command sometime when soon connected.
#  Maybe SSH demon still not wake up.)
# 時間を開け、SSHに接続
# (activeになった直後にSSHへすぐ接続すると、コマンドがハングアップするため)

sleep 30
$tugboat ssh $droplet -i $latestdroplet
Suspend Script
#!/bin/bash

# Copyright at Hirohisa Kawase.

# Specify path to your tugboat command if needed.
# tugboatコマンドのパスを必要ならば、指定して下さい。
tugboat='tugboat'

# Specify Droplet name to make snapshot.
# 保存するドロップレットの名前を指定して下さい。
droplet='MyDroplet'

# Specify snapshot name.
# スナップショット名を指定して下さい。
snapshot='MySnapshot'



# Make temporary file name
# 一時ファイル名生成

tempfile=`mktemp`

# Get droplets.
# 起動中のドロップレットの取得

$tugboat droplets > $tempfile
cat $tempfile

# Get latest droplet id.
# 最後に作成されたドロップレットの取得

awkcommand="/^$droplet \(ip: / { match(\$0, /id: (.+)\)/, mt); print mt[1] }"
latestdroplet=`awk -e "$awkcommand" $tempfile | sort -r | head -n 1`

if [ -z $latestdroplet ]
then
    echo Can\'t find droplet by named \'$droplet\' 1>&2
    exit 1
fi

# Halt it and wait it.
# 電源をoffにし、終了するまで待つ。

$tugboat halt $droplet -i $latestdroplet -h
$tugboat wait $droplet -i $latestdroplet -s off


# Take a snapshot.
# スナップショットの取得

$tugboat snapshot $snapshot $droplet -i $latestdroplet

# After processing, it turn on. So wait it.
# 処理が終わると、自動的に起動する。そのため、それを待つ

$tugboat wait $droplet -i $latestdroplet -s active

# Destroy the droplet.
# ドロップレットの削除

$tugboat destroy $droplet -i $latestdroplet -c
Cleanup Script
#!/bin/bash

# Copyright on Hirohisa Kawase.

# Specify path to your tugboat command if needed.
# tugboatコマンドのパスを必要ならば、指定して下さい。
tugboat='tugboat'

# Specify snapshot name.
# スナップショット名を指定して下さい。
snapshot='MySnapshot'

# Number of holding snapshots.
# 残しておくスナップショットの数
remain='1'



# Make temporary file name
# 一時ファイル名生成

tempfile=`mktemp`

# Get images.
# イメージの取得

$tugboat images > $tempfile

cat $tempfile

# Get image ids to destroy.
# 削除するイメージのIDを取得する。

awkcommand="/$snapshot \(id: .+,/ { match(\$0, /\(id: (.+),/, mt); print mt[1] }"
sedcommand="1,$remain d"
destroyimages=`awk -e "$awkcommand" $tempfile | sort -r | sed -e "$sedcommand"`

if [ -z $destroyimages ]
then
    echo There are no snapshot images to destroy. 1>&2
    exit 1
fi

# Destroy images.
# スナップショットイメージを削除する。

for image in ${destroyimages}
do
    $tugboat destroy_image $snapshot -i $image -c
done