LoginSignup
1
1

More than 3 years have passed since last update.

目的

社内で色々なバックアップをしていましたが、個別にbashを書いていてメンテナンスしにくいと思ったので、Rubyでまとめてみました。

仕様

  1. バックアップしたい対象はそれぞれのサーバーで事前に準備(pg_dump等)
  2. バックアップを集約するサーバーで今回のプログラムを実行
  3. scpかrsyncのコピーコマンドとバックアップサーバー内の古いバックアップの削除コマンドをサポート
  4. コマンドの実行に失敗した場合はslackに通知
  5. バックアップの設定はyamlファイルで管理
  6. yamlファイルはERBを通して実行する

プログラム

Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'slack-ruby-client'
gem 'systemu'
gem 'hashie'
backup.rb
require 'systemu'
require 'slack-ruby-client'
require 'hashie'
require 'erb'
require 'yaml'
require 'fileutils'

def notification(config, content)
  Slack.configure do |cfg|
    cfg.token = config.slack.token
  end
  client = Slack::Web::Client.new
  client.auth_test
  text = "#{config.name}\n#{content}"
  client.chat_postMessage(channel: config.slack.channel, text: text, as_user: true)
end

def read_config(path)
  Hashie::Mash.new(YAML.load(ERB.new(File.read(path)).result))
end

def scp(command)
  status, stdout, stderr = systemu "/usr/bin/scp #{command.from} #{command.to}"
  raise "fail scp" unless status.success?
end

def rsync(command)
  status, stdout, stderr = systemu "/usr/bin/rsync -azq --delete #{command.from} #{command.to}"
  raise "fail rsync" unless status.success?
end

def clean(command)
  ymd = (Date.today - command.days ).strftime("%Y%m%d")
  re = Regexp.new(command.name_match)
  Dir::entries(command.dir).each do |it|
    if re =~ it
      FileUtils.rm_rf(File.join(command.dir, it)) if $1 < ymd
    end
  end
end

config = read_config(ARGV[0])
begin
  config.commands.each do |command|
    case command.type
    when 'scp' then
      scp(command)
    when 'rsync' then
      rsync(command)
    when 'clean' then
      clean(command)
    end
  end
rescue Exception => e
  # エラーのfull_messageにtermcapが入るのを防いでいる
  $stderr = $stdout
  notification(config, e.full_message)
  #puts e.full_message
end
webserver.yaml
name: webserver

slack:
  token: <%= ENV['SLACK_API_TOKEN'] %>
  channel: "#backup"

commands:
  - type: scp
    from: vps01:/home/me/backup/<%= Date.today.strftime("%Y%m%d") %>.tar.bz2
    to: /home/me/backup/webserver
  - type: clean
    name_match: ^(\d\d\d\d\d\d\d\d)\.
    dir: /home/me/backup/webserver
    days: 5
git.yaml
name: git backup

slack:
  token: <%= ENV['SLACK_API_TOKEN'] %>
  channel: "#backup"

commands:
  - type: rsync
    from: vps01:/var/git/
    to: /home/me/backup/git/<%= Date.today.strftime("%Y%m%d") %>
  - type: clean
    name_match: ^(\d\d\d\d\d\d\d\d)$
    dir: /home/me/backup/git
    days: 40
SLACK_API_TOKEN=xxxx bundle exec ruby backup.sh webserver.yaml
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1