Created
November 22, 2018 09:31
-
-
Save ConoHa/de1eb4c0cd4bd93df69155a804bda7fa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eu | |
readonly ARCHIVER_DIR_PREFIX="${HOME}/.minecraft_archiver" | |
readonly ARCHIVER_BIN_DIR="${ARCHIVER_DIR_PREFIX}/bin" | |
readonly ARCHIVER_WORK_DIR="${ARCHIVER_DIR_PREFIX}/work" | |
readonly SYSTEMD_UNIT_DIR="/usr/lib/systemd/system/" | |
yum -y update | |
yum -y upgrade | |
yum -y install jq | |
mkdir -p ${ARCHIVER_DIR_PREFIX} ${ARCHIVER_BIN_DIR} ${ARCHIVER_WORK_DIR} | |
# backup.sh | |
cat <<- 'EOF' >> ${ARCHIVER_BIN_DIR}/backup.sh | |
#!/bin/bash | |
#-*- mode:shellscript | |
set -eu | |
readonly ARCHIVER_DIR_PREFIX="/root/.minecraft_archiver" | |
readonly ARCHIVER_BIN_DIR="${ARCHIVER_DIR_PREFIX}/bin" | |
readonly ARCHIVER_WORK_DIR="${ARCHIVER_DIR_PREFIX/work}" | |
readonly MINECRAFT_DIR="/opt/minecraft_server" | |
readonly MINECRAFT_SERVER_SERVICE="/etc/systemd/system/minecraft-server.service" | |
readonly ARCHIVE_CONTAINER="minecraftarchives" | |
function getNewToken() { | |
local readonly tenantID=${1} | |
local readonly apiusername=${2} | |
local readonly apipassword=${3} | |
local readonly json_auth='{ "auth": { "tenantId": "'${tenantID}'", "passwordCredentials": { "username": "'${apiusername}'", "password": "'${apipassword}'" } } }' | |
local readonly resp_tyo1=$(curl -f -X POST "https://identity.tyo1.conoha.io/v2.0/tokens" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
-d "${json_auth}" 2> /dev/null ) | |
local readonly resp_tyo2=$(curl -f -X POST "https://identity.tyo2.conoha.io/v2.0/tokens" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
-d "${json_auth}" 2> /dev/null ) | |
local token_resp="" | |
if [ -n "${resp_tyo1}" ]; then | |
token_resp=${resp_tyo1} | |
elif [ -n "${resp_tyo2}" ]; then | |
token_resp=${resp_tyo2} | |
else | |
echo "failed to get token" | |
exit 1 | |
fi | |
echo ${token_resp} | |
} | |
function putObject(){ | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
local readonly dest_object=${3} | |
local readonly source_file=${4} | |
curl -X PUT \ | |
-H "X-Auth-Token: ${token}" \ | |
-H "Accept: application/json" \ | |
-H "Content-Type: application/json" \ | |
"${objstr_endpoint}/${ARCHIVE_CONTAINER}/${dest_object}" \ | |
-T "${source_file}" 2> /dev/null | |
echo "${objstr_endpoint}/${ARCHIVE_CONTAINER}/${dest_object}" | |
} | |
function createMinecraftArchive() { | |
local readonly minecraft_current_ver=$( ls ${MINECRAFT_DIR}/*.jar | cut -d '/' -f4 | sed -e "s/minecraft_server\.//" -e "s/\.jar//" ) | |
local readonly timestamp=$(date +'%Y-%m-%dT%H-%M-%S') | |
local readonly archive_dir_name="minecraft-${minecraft_current_ver}-${timestamp}" | |
local readonly archive_temp="${ARCHIVER_WORK_DIR}/${archive_dir_name}" | |
mkdir -p ${archive_temp} | |
cd ${ARCHIVER_WORK_DIR} | |
cp -r ${MINECRAFT_DIR}/[^backup]* ${archive_temp} | |
cp ${MINECRAFT_SERVER_SERVICE} ${archive_temp} | |
tar czf "${ARCHIVER_WORK_DIR}/${archive_dir_name}.tar.gz" "${archive_dir_name}" | |
rm -rf ${archive_temp} | |
echo ${archive_temp}.tar.gz | |
} | |
function checkMinecraftContainerExist(){ | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
local readonly containers_resp=$(curl -X GET \ | |
-H "X-Auth-Token: ${token}" \ | |
-H "Accept: application/json" \ | |
-H "Content-Type: application/json" \ | |
"${objstr_endpoint}" 2> /dev/null ) | |
echo ${containers_resp} | jq -c ".[]|select(.\"name\"==\"${ARCHIVE_CONTAINER}\")" | wc -l | |
} | |
function createBackupContainer() { | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
if [ $(checkMinecraftContainerExist ${token} ${objstr_endpoint}) -eq 0 ]; then | |
echo "Minecraft archive container is not exist. Create the container." | |
local readonly createcontainer_resp=$( curl -X PUT \ | |
-H "X-Auth-Token: ${token}" \ | |
-H "Accept: application/json" \ | |
-H "Content-Type: application/json" \ | |
"${objstr_endpoint}/${ARCHIVE_CONTAINER}" 2> /dev/null ) | |
fi | |
} | |
function main() { | |
source ${ARCHIVER_DIR_PREFIX}/apiinfo | |
local readonly token_resp=$(getNewToken ${tenantid} ${apiuser} ${apipass}) | |
local readonly token=$(echo "${token_resp}" | jq -r ".\"access\".\"token\".\"id\"") | |
local readonly objstr_endpoint=$(echo "${token_resp}" | jq -r ".\"access\".\"serviceCatalog\"[] | select (.\"type\" == \"object-store\") | .\"endpoints\"[0].\"publicURL\"") | |
local readonly archive_path=$(createMinecraftArchive) | |
local readonly archive_filename=$(echo ${archive_path} | rev | cut -d '/' -f1 | rev) | |
createBackupContainer ${token} ${objstr_endpoint} | |
putObject ${token} ${objstr_endpoint} ${archive_filename} ${archive_path} | |
rm ${archive_path} | |
} | |
main $@ | |
EOF | |
chmod +x ${ARCHIVER_BIN_DIR}/backup.sh | |
# listBackups.sh | |
cat <<- 'EOF' >> ${ARCHIVER_BIN_DIR}/listBackups.sh | |
#!/bin/bash | |
#-*- mode:shellscript | |
set -eu | |
readonly ARCHIVER_DIR_PREFIX="${HOME}/.minecraft_archiver" | |
readonly ARCHIVER_BIN_DIR="${ARCHIVER_DIR_PREFIX}/bin" | |
readonly ARCHIVER_WORK_DIR="${ARCHIVER_DIR_PREFIX/work}" | |
readonly MINECRAFT_DIR="/opt/minecraft_server" | |
readonly MINECRAFT_SERVER_SERVICE="/etc/systemd/system/minecraft-server.service" | |
readonly ARCHIVE_CONTAINER="minecraftarchives" | |
function getNewToken() { | |
local readonly tenantID=${1} | |
local readonly apiusername=${2} | |
local readonly apipassword=${3} | |
local readonly json_auth='{ "auth": { "tenantId": "'${tenantID}'", "passwordCredentials": { "username": "'${apiusername}'", "password": "'${apipassword}'" } } }' | |
local readonly resp_tyo1=$(curl -f -X POST "https://identity.tyo1.conoha.io/v2.0/tokens" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
-d "${json_auth}" 2>/dev/null) | |
local readonly resp_tyo2=$(curl -f -X POST "https://identity.tyo2.conoha.io/v2.0/tokens" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
-d "${json_auth}" 2>/dev/null) | |
local token_resp="" | |
if [ -n "${resp_tyo1}" ]; then | |
token_resp=${resp_tyo1} | |
elif [ -n "${resp_tyo2}" ]; then | |
token_resp=${resp_tyo2} | |
else | |
echo "failed to get token" | |
exit 1 | |
fi | |
echo ${token_resp} | |
} | |
function getObjectList() { | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
local readonly response=$( curl -X GET \ | |
-H "X-Auth-Token: ${token}" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
"${objstr_endpoint}/${ARCHIVE_CONTAINER}" 2>/dev/null ) | |
echo $( echo ${response} | jq -r ".[].name" ) | |
} | |
function main(){ | |
source ${ARCHIVER_DIR_PREFIX}/apiinfo | |
local readonly token_resp=$(getNewToken ${tenantid} ${apiuser} ${apipass}) | |
local readonly token=$(echo "${token_resp}" | jq -r ".\"access\".\"token\".\"id\"") | |
local readonly objstr_endpoint=$(echo "${token_resp}" | jq -r ".\"access\".\"serviceCatalog\"[] | select (.\"type\" == \"object-store\") | .\"endpoints\"[0].\"publicURL\"") | |
for obj in $(getObjectList ${token} ${objstr_endpoint}) | |
do | |
echo ${obj} | |
done | |
} | |
main $@ | |
EOF | |
chmod +x ${ARCHIVER_BIN_DIR}/listBackups.sh | |
# deleteBackups.sh | |
cat <<- 'EOF' >> ${ARCHIVER_BIN_DIR}/deleteBackups.sh | |
#!/bin/bash | |
#-*- mode:shellscript | |
set -eu | |
readonly ARCHIVER_DIR_PREFIX="${HOME}/.minecraft_archiver" | |
readonly ARCHIVER_BIN_DIR="${ARCHIVER_DIR_PREFIX}/bin" | |
readonly ARCHIVER_WORK_DIR="${ARCHIVER_DIR_PREFIX}/work" | |
readonly MINECRAFT_DIR="/opt/minecraft_server" | |
readonly MINECRAFT_SERVER_SERVICE="/etc/systemd/system/minecraft-server.service" | |
readonly ARCHIVE_CONTAINER="minecraftarchives" | |
function getNewToken() { | |
local readonly tenantID=${1} | |
local readonly apiusername=${2} | |
local readonly apipassword=${3} | |
local readonly json_auth='{ "auth": { "tenantId": "'${tenantID}'", "passwordCredentials": { "username": "'${apiusername}'", "password": "'${apipassword}'" } } }' | |
local readonly resp_tyo1=$(curl -f -X POST "https://identity.tyo1.conoha.io/v2.0/tokens" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
-d "${json_auth}" 2>/dev/null) | |
local readonly resp_tyo2=$(curl -f -X POST "https://identity.tyo2.conoha.io/v2.0/tokens" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
-d "${json_auth}" 2>/dev/null) | |
local token_resp="" | |
if [ -n "${resp_tyo1}" ]; then | |
token_resp=${resp_tyo1} | |
elif [ -n "${resp_tyo2}" ]; then | |
token_resp=${resp_tyo2} | |
else | |
echo "failed to get token" | |
exit 1 | |
fi | |
echo ${token_resp} | |
} | |
function deleteObject(){ | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
local readonly target_obj=${3} | |
echo "Deleting ${target_obj}" | |
curl -X DELETE \ | |
-H "X-Auth-Token: ${token}" \ | |
-H "Accept: application/json" \ | |
-H "Content-Type: application/json" \ | |
"${objstr_endpoint}/${ARCHIVE_CONTAINER}/${target_obj}" 2>/dev/null | |
} | |
function deleteContainer(){ | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
echo "Deleting ${ARCHIVE_CONTAINER} container" | |
curl -X DELETE \ | |
-H "X-Auth-Token: ${token}" \ | |
-H "Accept: application/json" \ | |
-H "Content-Type: application/json" \ | |
"${objstr_endpoint}/${ARCHIVE_CONTAINER}" 2>/dev/null | |
} | |
function getObjectList() { | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
local readonly response=$( curl -X GET \ | |
-H "X-Auth-Token: ${token}" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
"${objstr_endpoint}/${ARCHIVE_CONTAINER}" 2>/dev/null ) | |
echo $( echo ${response} | jq -r ".[].name" ) | |
} | |
function deleteAllObject(){ | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
for obj in $(getObjectList ${token} ${objstr_endpoint}) | |
do | |
deleteObject ${token} ${objstr_endpoint} ${obj} | |
done | |
} | |
function deleteAllObjectAndContainer(){ | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
deleteAllObject ${token} ${objstr_endpoint} | |
deleteContainer ${token} ${objstr_endpoint} | |
} | |
function main() { | |
source ${ARCHIVER_DIR_PREFIX}/apiinfo | |
local readonly token_resp=$(getNewToken ${tenantid} ${apiuser} ${apipass}) | |
local readonly token=$(echo "${token_resp}" | jq -r ".\"access\".\"token\".\"id\"") | |
local readonly objstr_endpoint=$(echo "${token_resp}" | jq -r ".\"access\".\"serviceCatalog\"[] | select (.\"type\" == \"object-store\") | .\"endpoints\"[0].\"publicURL\"") | |
local readonly target=${1} | |
read -r -p "Delete ${target} [y/N]? " confirm | |
case $confirm in | |
[yY]) | |
case ${target} in | |
"all") | |
deleteAllObjectAndContainer ${token} ${objstr_endpoint} | |
;; | |
*) | |
deleteObject ${token} ${objstr_endpoint} ${target} | |
;; | |
esac | |
;; | |
[nN]) | |
exit 0 | |
;; | |
*) | |
echo "Invalid input." | |
exit 0 | |
;; | |
esac | |
} | |
main $@ | |
EOF | |
chmod +x ${ARCHIVER_BIN_DIR}/deleteBackups.sh | |
# restoreFromBackup.sh | |
cat <<- 'EOF' >> ${ARCHIVER_BIN_DIR}/restoreFromBackup.sh | |
#!/bin/bash | |
#-*- mode:shellscript | |
set -eu | |
readonly ARCHIVER_DIR_PREFIX="${HOME}/.minecraft_archiver" | |
readonly ARCHIVER_BIN_DIR="${ARCHIVER_DIR_PREFIX}/bin" | |
readonly ARCHIVER_WORK_DIR="${ARCHIVER_DIR_PREFIX}/work" | |
readonly MINECRAFT_DIR="/opt/minecraft_server" | |
readonly MINECRAFT_SERVER_SERVICE="/etc/systemd/system/minecraft-server.service" | |
readonly ARCHIVE_CONTAINER="minecraftarchives" | |
function getNewToken() { | |
local readonly tenantID=${1} | |
local readonly apiusername=${2} | |
local readonly apipassword=${3} | |
local readonly json_auth='{ "auth": { "tenantId": "'${tenantID}'", "passwordCredentials": { "username": "'${apiusername}'", "password": "'${apipassword}'" } } }' | |
local readonly resp_tyo1=$(curl -f -X POST "https://identity.tyo1.conoha.io/v2.0/tokens" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
-d "${json_auth}" 2>/dev/null ) | |
local readonly resp_tyo2=$(curl -f -X POST "https://identity.tyo2.conoha.io/v2.0/tokens" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
-d "${json_auth}" 2>/dev/null ) | |
local token_resp="" | |
if [ -n "${resp_tyo1}" ]; then | |
token_resp=${resp_tyo1} | |
elif [ -n "${resp_tyo2}" ]; then | |
token_resp=${resp_tyo2} | |
else | |
echo "failed to get token" | |
exit 1 | |
fi | |
echo ${token_resp} | |
} | |
function getObject() { | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
local readonly target_archive=${3} | |
cd ${ARCHIVER_WORK_DIR} | |
curl -X GET \ | |
-H "X-Auth-Token: ${token}" \ | |
-H 'Accept: application/json' \ | |
-H 'Content-Type: application/json' \ | |
"${objstr_endpoint}/${ARCHIVE_CONTAINER}/${target_archive}" 2>/dev/null > ${target_archive} | |
} | |
function restore(){ | |
local readonly token=${1} | |
local readonly objstr_endpoint=${2} | |
local readonly archive_name=${3} | |
local readonly archive_dir=$(echo ${archive_name} | sed -e "s/\.tar\.gz//") | |
cd ${ARCHIVER_WORK_DIR} | |
getObject ${token} ${objstr_endpoint} ${archive_name} | |
systemctl disable --now minecraft-server | |
tar xf ${archive_name} | |
cp -r ${archive_dir}/* ${MINECRAFT_DIR} | |
mv ${MINECRAFT_DIR}/minecraft-server.service ${MINECRAFT_SERVER_SERVICE} | |
chown minecraft:minecraft -R ${MINECRAFT_DIR} | |
systemctl daemon-reload | |
systemctl enable --now minecraft-server | |
rm -f ${archive_name} | |
rm -rf ${archive_dir} | |
echo "Restore complete" | |
} | |
function main(){ | |
local readonly target_archive=${1} | |
source ${ARCHIVER_DIR_PREFIX}/apiinfo | |
local readonly token_resp=$(getNewToken ${tenantid} ${apiuser} ${apipass}) | |
local readonly token=$(echo "${token_resp}" | jq -r ".\"access\".\"token\".\"id\"") | |
local readonly objstr_endpoint=$(echo "${token_resp}" | jq -r ".\"access\".\"serviceCatalog\"[] | select (.\"type\" == \"object-store\") | .\"endpoints\"[0].\"publicURL\"") | |
restore ${token} ${objstr_endpoint} ${target_archive} | |
} | |
main $@ | |
EOF | |
chmod +x ${ARCHIVER_BIN_DIR}/restoreFromBackup.sh | |
# uninstall.sh | |
cat <<- 'EOF' >> ${ARCHIVER_BIN_DIR}/uninstall.sh | |
#!/bin/bash | |
set -eu | |
readonly ARCHIVER_DIR_PREFIX="${HOME}/.minecraft_archiver" | |
readonly ARCHIVER_BIN_DIR="${ARCHIVER_DIR_PREFIX}/bin" | |
readonly ARCHIVER_WORK_DIR="${ARCHIVER_DIR_PREFIX}/work" | |
readonly SYSTEMD_UNIT_DIR="/usr/lib/systemd/system/" | |
read -r -p "Disable auto backup [y/N]? " confirm | |
case $confirm in | |
[yY]) | |
;; | |
[nN]) | |
exit 0 | |
;; | |
*) | |
echo "Invalid input." | |
exit 0 | |
;; | |
esac | |
read -r -p "Delete all backups [y/N]? " confirm | |
case $confirm in | |
[yY]) | |
${ARCHIVER_BIN_DIR}/deleteBackups.sh all | |
;; | |
[nN]) | |
;; | |
*) | |
echo "Invalid input." | |
exit 0 | |
;; | |
esac | |
systemctl disable --now backup-minecraft.timer | |
rm -rf ${ARCHIVER_DIR_PREFIX} | |
rm -rf ${SYSTEMD_UNIT_DIR}/backup-minecraft.* | |
echo "Uninstall complete." | |
EOF | |
chmod +x ${ARCHIVER_BIN_DIR}/uninstall.sh | |
cat <<- 'EOF' >> ${ARCHIVER_DIR_PREFIX}/apiinfo | |
local readonly tenantid="[Tenant ID]" | |
local readonly apiuser="[API User name]" | |
local readonly apipass="[API Password]" | |
EOF | |
cat <<- 'EOF' >> ${SYSTEMD_UNIT_DIR}/backup-minecraft.service | |
[Unit] | |
Description=Backup minecraft maps. | |
[Service] | |
Type=simple | |
ExecStart=/bin/bash /root/.minecraft_archiver/bin/backup.sh | |
[Install] | |
WantedBy=default.target | |
EOF | |
cat <<- 'EOF' >> ${SYSTEMD_UNIT_DIR}/backup-minecraft.timer | |
[Unit] | |
Description=Backup minecraft map data daily. | |
[Timer] | |
OnBootSec=1min | |
Persistent=true | |
OnCalendar=*-*-* 3:00:00 | |
RandomizedDelaySec=10min | |
[Install] | |
WantedBy=timers.target | |
EOF | |
systemctl daemon-reload |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment