BlogのBackupを定期的にとった方が良さそうなので、
mezzanine-admin-backupをインストールして、Backupしてみました。

環境情報

  • OS
    CentOS release 6.7 (Final)

  • Python Version
    Python 2.7.8

  • Package (必要そうなものだけ抜粋)
    Django (1.9.6)
    Mezzanine (4.1.0)


インストール手順

Bitbucketの情報量の少ないREADME.md参照しながら、インストールしていきます。

  • pip インストール

pip install mezzanine-admin-backup

  • OUTPUT
    パッケージがないと言われます…

      Could not find a version that satisfies the requirement mezzanine-admin-backup (from versions: )
    No matching distribution found for mezzanine-admin-backup
    

  • Bitbucketからzipファイルをダウンロード1。

wget https://bitbucket.org/joshcartme/mezzanine-admin-backup/get/730bdd7ca39d.zip

  • unzip

unzip 730bdd7ca39d.zip

  • 解凍したディレクトリ内にあるadmin_backupディレクトリをmezzanineプロジェクト内にコピー
    cd joshcartme-mezzanine-admin-backup-730bdd7ca39d
    

cp -r admin_backup ${MEZZANINE_PROJECT_DIR}


url.pyの編集

  • urls.py を編集、以下の記述を追加する。(コメント記述はなんとなく他のURL定義に合わせてみました)
    README.mdにbefore the admin site is addedありますが、
    実際以下のように書かないと、URLが404 not foundなります。

urlpatterns = i18n_patterns("",
    # MEZZANINE ADMIN BACKUP
    # ----------------------
    url("^admin/backup/$", "admin_backup.views.admin_backup", name="admin_backup"),
    # Change the admin prefix here to use an alternate URL for the
    # admin interface, which would be marginally more secure.
    ("^admin/", include(admin.site.urls)),
)


動作確認

  • 以下のURLでbackup要求が実行できるので、URLにアクセスする。

    ${YOUR_SITE}/jp/admin/backup/
    

  • エラー画面に遷移

エラー画面

  • Apacheのエラーログを確認
    pg_dumpでエラーが発生しています…
    理由がよくわからない。

pg_dump: [アーカイバ(db)] データベース"xxx"への接続が失敗しました: fe_sendauth: no password supplied

  • admin_backupフォルダのviews.pyを開く
    admin_backup(request)いうそのものなメソッドがありますが、
    コメントに# requires that a .pgpass file is configuredあります。
    以下の記事の通り、
    postgressのpg_dumpコマンドは、.pgpassファイルを置くか、
    postgreSQLで接続パスワード自動設定 - yummy-yummy
    または、os.environ["PGPASSWORD"]設定してあげる必要があります。

  • view.py(一部抜粋)

    @staff_member_required
    def admin_backup(request):
        '''
        Backs up the media and database of a Mezzanine project and returns it as a
        zip file to the admin requesting it
        '''
        if os.path.exists(BACKUP_DIR):
            shutil.rmtree(BACKUP_DIR)
        os.mkdir(BACKUP_DIR)
        os.mkdir(SQL_BACKUP_DIR)
    
        zip_path = '%s/backup-%s.zip' % (BACKUP_DIR, str(now()).replace(' ', '_'))
        zipf = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED)
    
        # backup database[s]
        for db in settings.DATABASES:
            db = settings.DATABASES[db]
            if db['ENGINE'] == 'django.db.backends.sqlite3':
                if os.path.isabs(db['NAME']):
                    db_file = db['NAME']
                else:
                    db_file = '%s/%s' % (settings.PROJECT_ROOT, db['NAME'])
                shutil.copy(db_file, SQL_BACKUP_DIR)
    
            elif db['ENGINE'] == 'django.db.backends.mysql':
                os.system('mysqldump -u %s %s -p%s > %s/%s.sql' % (
                    db['USER'],
                    db['NAME'],
                    db['PASSWORD'],
                    SQL_BACKUP_DIR,
                    db['NAME']))
    
            elif db['ENGINE'] == 'django.db.backends.postgresql_psycopg2':
                # requires that a .pgpass file is configured
                os.system('pg_dump -Fc -w -U %s -f %s/%s.sql %s' % (
                    db['USER'],
                    SQL_BACKUP_DIR,
                    db['NAME'],
                    db['NAME']))
    
        zipdir(SQL_BACKUP_DIR, zipf)
        # add the media library to the zip
        zipdir(settings.MEDIA_ROOT, zipf)
        zipf.close()
    
        return send_file(zip_path)
    

  • settings.pyにos.environ["PGPASSWORD"]追加
    postgressとしては、.pgpass置くことを推奨しているっぽいですが、
    settings.pyos.environ["PGPASSWORD"]追加することにしました。

import os

# Set Postgress Password
# ---------------------
os.environ["PGPASSWORD"] = DATABASES["default"]["PASSWORD"]

  • 再度URLにアクセスする。

    ${YOUR_SITE}/jp/admin/backup/
    

  • またエラー画面に遷移

エラー画面

[Sat May 07 00:51:09 2016] [error] TypeError: __init__() got an unexpected keyword argument 'mimetype'
[Sat May 07 00:57:08 2016] [notice] caught SIGTERM, shutting down

  • view.pyを修正
    response = HttpResponse(content_type=mimetype)修正

def send_file(path, filename = None, mimetype = None):

    if filename is None: filename = os.path.basename(path)

    if mimetype is None:
        mimetype, encoding = mimetypes.guess_type(filename)

    """以下をコメントアウト"""
    #response = HttpResponse(mimetype=mimetype)
    """以下を追加"""
    response = HttpResponse(content_type=mimetype)
    response['Content-Disposition'] = 'attachment; filename=%s' %filename
    response.write(file(path, "rb").read())
    return response

  • 再度URLにアクセスする。

    ${YOUR_SITE}/jp/admin/backup/
    

  • 正常終了!!!
    zipファイルがダウンロードされて落ちてきます。
    解凍すると拡張子がsqlのファイルになります。

ダウンロード

  • リストア実行 以下の前提を満たした上で、リストアコマンドを実行します。

    • リストア対象のDATABASEが存在すること

    • DATABASE上のユーザー(ロール?)が存在すること

pg_restore -d ${DATABASE_NAME} -U ${USER_NAME} xxxdb.sql

dumpの形式がアーカイブ形式なので、pg_restoreでのリストアとなります。


必要に応じて…

README.mdにも記載がありますが、
settings.py記述を追加することで、
管理画面のダッシュボードにダウンロードリンクの追加ができそうです。

  • settings.py#INSTALLED_APPSに“admin_backup”を追加

INSTALLED_APPS = (
    "admin_backup",
    "clean_blog",
    "mezzanine_pagedown",

  • settings.py#DASHBOARD_TAGSに“admin_backup_tags.admin_backup”を追加

# DASHBOARD_TAGS = (
#     ("blog_tags.quick_blog", "mezzanine_tags.app_list"),
#     ("comment_tags.recent_comments",),
#     ("mezzanine_tags.recent_actions",),
# )
#
# MEZZANINE ADMIN BACKUP
DASHBOARD_TAGS = (
    ("blog_tags.quick_blog", "mezzanine_tags.app_list"),
    ("admin_backup_tags.admin_backup","comment_tags.recent_comments",),
    ("mezzanine_tags.recent_actions",),
)

  • ダッシュボードを表示
    ダッシュボードにBackupリンクが追加され、
    リンク押下でDumpファイルのダウンロードが可能になります。

Backupリンク


補足.Backupディレクトリは変更できる

  • views.py(一部抜粋)
    デフォルトだと、${PROJECT_ROOT}/admin_backupsに、
    Backupディレクトリと、dumpファイル類が保存されますが、
    settings.ADMIN_BACKUP_DIR_NAME設定することで、
    ディレクトリは変更可能です。
    あくまで、PROJECT_ROOT配下なのでデフォルトのままでいい気がしますが

try:
    BACKUP_DIR = '%s/%s' % (settings.PROJECT_ROOT, settings.ADMIN_BACKUP_DIR_NAME)
except AttributeError:
    BACKUP_DIR = '%s/admin_backups' % settings.PROJECT_ROOT
SQL_BACKUP_DIR = '%s/sql' % BACKUP_DIR

以上です。

コメント