SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

【php】さくらのクラウドのAPIで日次バックアップ作成スクリプト

問題

さくらのクラウドのAPIを使って、仮想マシンのディスクのアーカイブを毎日自動したいんですけど。自動化できますか?

sakura cloud

答え

phpを使って書いてみました。

アーカイブの作成のスクリプトを1日1回実行と、最新の1世代だけを残してそれ以外は掃除するスクリプトを定期的に実行する作戦で対応してみました。

APIを呼ぶだけならcurlコマンドのみでもよさそうですが、レスポンスがJSONなので、レスポンスの内容から情報を得たい場合は、phpはよいと思います。

1、ディスクのアーカイブを作成するphpスクリプト

<?php

//APIキーは管理画面にて作成する
$access_token = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
$access_token_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

//拠点に応じてAPIのURLが違う
$url = 'https://secure.sakura.ad.jp/cloud/zone/tk1a/api/cloud/1.1/archive'; // 東京第1ゾーン
//$url = 'https://secure.sakura.ad.jp/cloud/zone/is1a/api/cloud/1.1/archive'; // 石狩第1ゾーン
//$url = 'https://secure.sakura.ad.jp/cloud/zone/is1b/api/cloud/1.1/archive'; // 石狩第2ゾーン
//$url = 'https://secure.sakura.ad.jp/cloud/zone/tk1v/api/cloud/1.1/archive'; // Sandbox

//後で削除することを考慮してアーカイブの名前にルールを決めておく
exec('curl --user "' . $access_token . '":"' . $access_token_secret . '" -X POST -d \'{"Archive":{"Name":"archive-192-000-002-123","Description":"192-000-002-123のバックアップ","SourceDisk":{"ID":"123456789000"}}}\' ' . $url, $e, $r);

//エラーがあった場合の処理
$r = json_decode($e[0]);
if ($r->Success) {
        mail('test@example.com', 'OK!', $e[0]);
} else {
        mail('test@example.com', 'Error!', $e[0]);
}

2、最新1世代以外を見つけたら削除するphpスクリプト

<?php
/**
 * ・注意
 * 拠点に応じてAPIのURLが違うので書き換えてください
 * https://secure.sakura.ad.jp/cloud/zone/tk1a/api/cloud/1.1/ (東京第1ゾーン)
 * https://secure.sakura.ad.jp/cloud/zone/is1a/api/cloud/1.1/ (石狩第1ゾーン)
 * https://secure.sakura.ad.jp/cloud/zone/is1b/api/cloud/1.1/ (石狩第2ゾーン)
 * https://secure.sakura.ad.jp/cloud/zone/tk1v/api/cloud/1.1/ (Sandbox)
 */

//APIキーは管理画面にて作成する
$access_token = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
$access_token_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

//新しい順に並び替えるときに使用する関数
function xxx($x, $y)
{
        if ($x->CreatedAt == $y->CreatedAt) {
                return 0;
        }
        return ($x->CreatedAt < $y->CreatedAt) ? -1 : 1;
}

//現状のアーカイブ一覧を取得
$archives = array();
$json = file_get_contents('https://' . $access_token . ':' . $access_token_secret . '@secure.sakura.ad.jp/cloud/zone/tk1a/api/cloud/1.1/archive');
$r = json_decode($json);
if ($r->Archives && is_array($r->Archives)) {
        foreach ($r->Archives as $v) {
		//名前を手掛かりにしてアーカイブ自動作成処理で作ったアーカイブを探す
                if (strpos($v->Name, 'archive-192-000-002-123') === 0 && $v->Availability == 'available' && $v->Scope == 'user') {
                        $archives[$v->Name][] = $v;
                }
        }
}

//最新のアーカイブを残して残りを消す
foreach ($archives as $name => $a) {
        usort($a, 'xxx');
        $v = array_pop($a);
        if ($a && is_array($a)) {
                foreach ($a as $v) {
                        exec('curl --user "' . $access_token . '":"' . $access_token_secret . '" -X DELETE https://secure.sakura.ad.jp/cloud/zone/tk1a/api/cloud/1.1/archive/' . $v->ID, $e, $r);
                }
        }
}

cron設定例

0 3 * * * /usr/bin/php /xxx/yyy/create-archive.php
*/15 * * * * /usr/bin/php /xxx/yyy/gc-archive.php

AM3時にアーカイブ作成を依頼。アーカイブ作成の完了は、5分後か10分後か30分後かいつになるかわからない。容量次第。サービスの状況次第。とにかくここでできるのは、作成の依頼まで。

15分おきにチェックして、いつになるかわからないアーカイブ作成完了を待って、最新1世代だけ残して削除する。

メモ

アーカイブが完成すると課金されるので、完成したアーカイブが2世代存在する時間を極力減らしたい場合は、チェックの頻度を上げるとよいかもしれない。

チェックの頻度は上げたくて、無駄にAPIを呼ぶのを避けたい場合で、対象のディスクが1つしかないなど単純な状況では、その日のアーカイブ削除が終わったらそれ以上はAPIに問い合わせをしないように処理を追加するとよいかもしれない。

curlコマンドを使ったり、file_get_contents関数を使ったり、統一感がなかったなと後で思いました。気になる方は直してください…

自動バックアップ機能が提供されていますが、まだベータ版です。 http://cloud-news.sakura.ad.jp/autobackup/

関連するメモ

コメント