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でも良いんですが、よりお手軽ですからね。スナップショットに保存したほうが。