Digital Ocean起動・終了スクリプト、API直叩きバージョン
タグ: 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でも良いんですが、よりお手軽ですからね。スナップショットに保存したほうが。