Digital Ocean起動・終了スクリプト、API直叩きバージョン

Tags : DigitalOcean  

Digital Ocean操作を行うtugboatという、サードパーティ静のコマンドツールを見つけたので、それらを利用して、定期的な起動・終了を簡単にできるシェルスクリプトを紹介していました。

ところがです、マシンのOSを再インストールしたせいなのか、はたまたAPI側の使用が変更されたせいなのか、「イベントが既にどうたらこうたら」と表示され、うまく動かなくなってしましました。

ちょうど、このサイトを含め、ドキュメントサイトの調子がおかしくなった時の、バックアップをDigital Oceanに作成している途中だったので、困りました。

しかたありません。しょうが無いので、tugboatを使用せず、APIを直接叩くバージョンを作成しました。

変更点

tugboatコマンドツールを使用せず、cURLとJSON操作コマンドツールのjqを使用し、前回と同様の機能を実装しています。一部表示や選択をグラフィカルに行うため、dialogコマンドツールを使用しています。

Linux系のディストリビューションなら、通常dialogはデフォルトでインストールされていると思います。残りのcURLとJSONはデフォルトでインストールされていないものも多いですのが、リポジトリーには含まれていると思いますので、インストールは難しくないでしょう。

機能的な変更点は一点だけです。起動スクリプトで最後にSSHで接続するのを止めました。接続はsshコマンドを直接叩くか、tugboatなどを利用するほうが、ワークフロー的に便利かと思います。最後に接続しても、一度切断したら、再接続時はこうしたコマンドツールを使用する必要がありますからね。

それに伴い、各シェルスクリプトでAPIキーなどの設定が必要になります。スクリプトの先頭にまとめてありますので、適当に値を設定してください。

起動スクリプト

指定した名前のスクリプトから、ドロップレットを起動します。デフォルト以外のサイズを使用したい場合は、--sizeを指定してください。

#!/bin/bash

#
# Digital Ocean ドロップレット起動シェル
#
# スナップショットからドロップレットを起動します
#
# curlとjqを使用します。Linuxのリポであれば
# 両方共通常は用意されていますが、デフォルトで
# インストールされていません。
# ご利用の際は、上記2コマンドを用意してください。
#
# Copyright by Hirohisa Kawase
#

### 設定値 ###

# ドロップレット名
# Droplet name
droplet='MyDroplet'

# スナップショット名
# Specify snapshot name.
snapshot='MySnapshot'



### Digital Ocean 設定値 ###

# クライアントキー
# Cliant key
cliant_key='自分のクライアントキー'

# APIキー
# API key
api_key='自分のAPIキー'

# ドロップレット生成リージョン
# Region
# Available: "sfo1", "nyc2", "ams2", "sgp1"
region='sgp1'

# ドロップレット生成時サイズ
# Droplet size
# Available:"512mb", "1gb", "2gb", "4gb", "8gb", "16gb", "32gb", "48gb", "64gb"
size='512mb'

# ドロップレット生成時設定SSHキー名
# SSH key names
# https://api.digitalocean.com/ssh_keys/?client_id=クライアントID&api_key=APIキーで取得できる値
# You can get by 'https://api.digitalocean.com/ssh_keys/?client_id=[client_id]&api_key=[api_key]'
# SSHキーに付けた名前を指定します。複数可能です。空白の場合、もしくはどれも登録されていない場合、
# パスワードによるログインになります。パスワードはDigitalOceanからメールで届けられます。
# If empty, password login.
ssh_keys='登録キー名1 登録キー名2'

# バックアップ
# Backup enable
backups_enabled='false'

# プライベートネットワーク
# Private networking
private_networking='false'






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

tempfile=`mktemp`




# Select droplet size
# ドロップレットサイズの選択

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

    # Get droplet sizes.
    # サイズ取得

    sizes=$(curl -X -sS GET -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/sizes | jq '.sizes []  | [.name, .slug]' | sed -e '/\[/d' -e '/\]/d' -e 's/,//' -e 's/"//g')

    dialog --menu "Droplet size? ドロップレットサイズ?" 15 40 12 $sizes 2> $tempfile

    if [ $? -ne 0 ]
    then
        echo Good by!
        exit 0
    fi

    size=$(cat $tempfile)

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

    echo $size is selected...
    sleep 3
fi




# Get snapshots by specified snapshot name.
# 名前に一致したスナップショットイメージのIDを取得する

jq_param=".images[] | select(.name == \"$snapshot\") | .id"
latest_snapshot=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key -d 'filter=my_images' https://api.digitalocean.com/images | jq "$jq_param" | sort -r | head -n 1)

if [ -z "${latest_snapshot}" ]
then
    echo Can\'t find a snapshot named \'$snapshot\'. 1>&2
    exit 1
fi




# Get SSH key IDs from names.
# SSHキー名からIDを取得

ret_json=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/ssh_keys)

keys=
for key in $ssh_keys
do
    jq_param=".ssh_keys[] | select(.name == \"$key\") | .id"
    keys=$keys','$(echo $ret_json | jq "$jq_param")
done

keys=$(echo $keys | sed -e 's/^,//')

if [ -z "${keys}" ]
then
    keys_param=
else
    keys_param="-d 'ssh_key_ids=$keys'"
fi




# Create backup parameter
# バックアップの引数作成

if [ "${backups_enabled}" = 'true' ]
then
    backups_param="-d 'backups_enabled=true'"
else
    backups_param=
fi



# Create private networking parameter
# プライベートネットワークの引数作成

if [ "${private_networking}" = 'true' ]
then
    private_net_param="-d 'private_networking=false'"
else
    private_net_param=
fi




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

ret_json=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key -d 'name='$droplet -d 'size_slug='$size -d 'image_id='$latest_snapshot -d 'region_slug='$region $keys_param $backups_param $private_net_param  https://api.digitalocean.com/droplets/new)

droplet_id=$(echo $ret_json | jq '.droplet.id')
event_id=$(echo $ret_json | jq '.droplet.event_id')




# Wait until kicked up
# 起動完了するまで待つ

i=0
(
until [ $i -gt 99 ]
do
    sleep 3
    i=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/events/$event_id | jq '.event.percentage' | sed -e 's/"//g')
    echo $i
done
) | dialog --gauge "Starting... 起動中..." 15 40




# Get info of created droplet.
# 作成したドロップレットの情報を取得

ret_json=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/droplets/$droplet_id)

ip=$(echo $ret_json | jq '.droplet.ip_address')

echo New droplet :
echo - name : $(echo $ret_json | jq '.droplet.name')
echo - id : $droplet_id
echo - IP : $ip
echo - Private IP : $(echo $ret_json | jq '.droplet.private_ip_address')
echo - Backup : $(echo $ret_json | jq '.droplet.backups_active')
echo - Status : $(echo $ret_json | jq '.droplet.status')

echo Done!!
echo 起動しました!

終了スクリプト

指定した名前のドロップレットを停止し、指定した名前でスナップショットを取ります。その後、破壊し課金されないようにします。

#!/bin/bash

#
# Digital Ocean ドロップレット終了シェル
#
# スナップショットを保存し、ドロップレットを破壊します。
#
# curlとjqを使用します。Linuxのリポであれば
# 両方共通常は用意されていますが、デフォルトで
# インストールされていません。
# ご利用の際は、上記2コマンドを用意してください。
#
# Copyright by Hirohisa Kawase
#


### 設定値 ###

# ドロップレット名
# Droplet name
droplet='MyDroplet'

# スナップショット名
# Specify snapshot name.
snapshot='MySnapshot'



### Digital Ocean 設定値 ###

# クライアントキー
# Cliant key
cliant_key='自分のクライアントキー'

# APIキー
# API key
api_key='自分のAPIキー'





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

tempfile=`mktemp`





# Get droplets info from name. If exist multily, just get one.
# ドロップレット名から起動中のドロップレットの情報を取得する。同じ名前で複数起動中の場合でも、一つだけ取得する。

jq_param=".droplets[] | select(.name == \"$droplet\") | .id"
droplet_id=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/droplets | jq "$jq_param" | head -n 1)




# Power off the droplet.
# 電源をoffにする。

event_id=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/droplets/$droplet_id/power_off | jq '.event_id')




# Wait until power off.
# 電源がoffになるまで待つ。

i=0
(
until [ $i -gt 99 ]
do
    sleep 1
    i=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/events/$event_id | jq '.event.percentage' | sed -e 's/"//g')
    echo $i
done
) | dialog --gauge "Power off... 電源off..." 15 40





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

event_id=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key -d 'name='$snapshot https://api.digitalocean.com/droplets/$droplet_id/snapshot | jq '.event_id')




# Wait until took the snapshot.
# スナップショットの取得完了まで待つ

i=0
(
until [ $i -gt 99 ]
do
    sleep 4
    i=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/events/$event_id | jq '.event.percentage' | sed -e 's/"//g')
    echo $i
done
) | dialog --gauge "Taking a snapshot... スナップショット取得中..." 15 40





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

event_id=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/droplets/$droplet_id/destroy | jq '.event_id')




# Wait until destoryed.
# ドロップレット破壊完了まで待つ


i=0
(
until [ $i -gt 99 ]
do
    sleep 3
    i=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/events/$event_id | jq '.event.percentage' | sed -e 's/"//g')
    echo $i
done
) | dialog --gauge "Destroy the droplet... ドロップレット破壊中..." 15 40


echo Done!!
echo 完了しました!

スナップショット整理シェル

スナップショットは同銘で保存されていきます。今のところ課金は開始されていませんが、ディスクイメージを圧縮した、スナップショットイメージのサイズに基づき、月ごとに課金されます。いつ課金が始まっても良いように、必要な数以外は削除しましょう。

#!/bin/bash

#
# Digital Ocean スナップショット片付けシェル
#
# 最新のものを残し、スナップショットを削除します。
#
# curlとjqを使用します。Linuxのリポであれば
# 両方共通常は用意されていますが、デフォルトで
# インストールされていません。
# ご利用の際は、上記2コマンドを用意してください。
#
# Copyright by Hirohisa Kawase
#


### 設定値 ###

# スナップショット名
# Specify snapshot name.
snapshot='MySnapshot'

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



### Digital Ocean 設定値 ###

# クライアントキー
# Cliant key
cliant_key='自分のクライアントキー'

# APIキー
# API key
api_key='自分のAPIキー'




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

tempfile=`mktemp`




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

jq_param=".images[] | select(.name == \"$snapshot\") | .id"
sed_param="1,$remain d"
latest_snapshot=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key -d 'filter=my_images' https://api.digitalocean.com/images | jq "$jq_param" | sort -r | sed -e "$sed_param")

if [ -z "${latest_snapshot}" ]
then
    echo Can\'t find a snapshot named \'$snapshot\' or less than specified remain snapshots. 1>&2
    exit 1
fi




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

for image in $latest_snapshot
do
    ret_json=$(curl -X GET -sS -d 'client_id='$cliant_key -d 'api_key='$api_key https://api.digitalocean.com/images/$image/destroy)
done

echo Done!!
echo 片付けました!

tugboatコマンドを利用するのとは異なり、イベントを直接待つようにしていますので、しばらくエラーは発生しないと思います。

まあ、Vagrantでも良いんですが、よりお手軽ですからね。スナップショットに保存したほうが。