Бекап на Amazon S3 больших файлов

Очередной подход к бекапу больших файлов на Amazon S3. Когда возникла необходимость сделать зеркало бекапов на Amazon S3 я обнаружил что s3cmd все еще не знает как заливать файлы свыше 5GB на Amazon S3, хотя API начал поддерживать объекты размером до 5TB.

Для меня загадка почему в интернете почти нету готовых bash-скриптов для бекапа файлов свыше 5GB на Amazon S3 используя s3cmd. Либо все заливают бекапы используя duplicity или аналоги, либо у всех маленькие бекапы. Пришлось писать самому. Скрипт довольно простой и требует только наличия s3cmd.

#!/usr/local/bin/bash

FILES_DIR="/usr/backup/files_month" # Директория с бекапами
S3_TMP="/usr/backup/to_s3" # Временная директория
S3_BUCKET="my.bucket" # S3 Бакет

if [ ! -d "$FILES_DIR" ]; then
  echo "Path '$FILES_DIR' is incorrect."
  exit 1
fi

if [ ! -d "$S3_TMP" ]; then
  echo "Path '$S3_TMP' is incorrect."
  exit 1
fi

rm -rf "$S3_TMP/*"
cd "$FILES_DIR"

for i in `find . -type f -name "*.gz"`;
do
    FILE_NAME=$(basename "$i");
    FILE_SIZE=$(stat -f %z $i);

    DIR_NAME=$(dirname "$i");
    DESTINATION="$S3_TMP${DIR_NAME:1}/";

    mkdir -p "$DESTINATION"

    # Тут regexp для игнорирования некоторых папок/файлов
    # в моем случае это папки user_testing и tmp
    if [[ "$i" =~ (user_testing|tmp) ]]; then
        echo "[ Ignored ]: $i";
    elif [ $FILE_SIZE -gt 4200000000 ]; then
        echo "[ Split ]: $i"
        split -b 4G "$i" "${DESTINATION}${FILE_NAME}."
    else
        echo "[ Copy ]: $i -> ${DESTINATION}${FILE_NAME}"
        cp "$i" "$DESTINATION$FILE_NAME";
    fi
done

s3cmd sync \
    --skip-existing \
    --delete-removed \
    "$S3_TMP/" \
    "s3://$S3_BUCKET/"

Удаление файлов в CloudApp

Совершенно неожиданно мой аккаунт на CloudApp сообщил о том, что закончилось бесплатное место. Для удаления накопившегося мусора я полез в личный кабинет и каково было мое удивление когда я там не обнаружил, не только кнопки удалить все, но даже кнопки выделить все на странице, для последующего удаления. Не долго думая накидал UserScript, который добавляет кнопку Select All на страницу c файлами.

Готовую версию можно скачать на GIST, работает в Chrome и Firefox.

cloudapp.user.js

// ==UserScript==
// @name         CloupApp Select all
// @match        http://my.cl.ly/*
// @author       dotzero
// @description  Add Select All button to CloudApp web interface
// ==/UserScript==

function main() {
    $('#toolbar').prepend('<li><a class="button" href="#" id="selall">Select all</a></li>');
    $('#selall').on("click", function(event){
        event.preventDefault();
        $('#listing').find('input:checkbox').click();
    });
}

function insert(callback) {
    var script = document.createElement("script");
    script.textContent = "(" + callback.toString() + ")();";
    document.body.appendChild(script);
}

insert(main);

Результат

CloudApp Select All

Кодировка файла в плагинах Sublime Text 2

Сегодня вышел 2165 билд прекрасного редактора SublimeText 2, а с ним приехало несколько интересных API методов, среди которых меня прежде всего заинтересовал view.encoding(), который возвращает кодировку открытого файла. Если же файл не открыт а просто создан и еще не сохранен, то этот метод возвращает строку ‘Undefined’.

Для своих плагинов которых работают с текстом я написал небольшой хак который позволяет абстрагироваться от этого, беря также в учет новую настройку ‘default_encoding’ которая содержит кодировку по-умолчанию для новых файлов.

def enc(self):
    if self.view.encoding() == 'Undefined':
        return self.view.settings().get('default_encoding', 'UTF-8')
    else:
        return self.view.encoding()

Резервное копирование базы данных Bitrix

Конечно в самом Bitrix есть механизм резервного копирования, а кроме того есть такая статья Резервное копирование по расписанию. Но не одно из решений не будет эффективным если в базе данных хранятся не только таблицы Bitrix, а бекапить надо только их. В результате написал небольшой скрипт взяв за основу оригинальный скрипт резервного копирования и переписав в нем алгоритм копирования базы данных в результате будут бекапится только Битриксовые таблицы с префиксом b_ , а кроме того в моих конфигах Битрикса есть закомментированные переменные, поэтому поправил парсинг конфиг файла чтобы не было конфликтов.

#!/bin/sh
doc_root=$1

if [ -z $doc_root ]; then
    echo Usage: $0 /path/to/document/root
    exit
fi

dbconn=$doc_root/bitrix/php_interface/dbconn.php

readcfg() {
    grep "^\$$1" $dbconn | sed 's/.*"\(.*\)".*/\1/'
}

host=`readcfg DBHost`
username=`readcfg DBLogin`
password=`readcfg DBPassword`
database=`readcfg DBName`

utf=`grep 'BX_UTF' $dbconn | grep true`

if [ -z "$utf" ]; then
   charset=cp1251
else
   charset=utf8
fi

mysql -h$host -u$username -p$password -N information_schema -e "SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA = '$database' AND TABLE_NAME LIKE 'b\_%'" > tables.txt
mysqldump -h$host -u$username -p$password --default-character-set=$charset $database `cat tables.txt` > dump.sql
tar czf dump_`date +%Y%m%d`.tgz dump.sql
rm -f tables.txt dump.sql

Множественное число существительных

Самый лаконичный вариант функции для выбора правильного склонения множественного числа на php.

$w1 = 'товар'; /* 1 */
$w2 = 'товара'; /* 2 */
$w5 = 'товаров'; /* 5 */

function plural_form($x, $w1, $w2, $w5)
{
    $w = array($w1, $w2, $w5);
    $d = ($p = $x % 100) % 10;

    return $x . ' ' . $w[$p == 11 || $d == 0 || ($p >= 10 && $p <= 20) || ($d >= 5 && $d <= 9) ? 2 : ($d == 1 ? 0 : 1)];
}