Skip to content

Instantly share code, notes, and snippets.

@ConoHa
Created November 22, 2018 09:31
Show Gist options
  • Save ConoHa/de1eb4c0cd4bd93df69155a804bda7fa to your computer and use it in GitHub Desktop.
Save ConoHa/de1eb4c0cd4bd93df69155a804bda7fa to your computer and use it in GitHub Desktop.
#!/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