diff --git a/.etc/config.sh b/.etc/config.sh new file mode 100644 index 0000000..f7469c0 --- /dev/null +++ b/.etc/config.sh @@ -0,0 +1,199 @@ +#!/bin/bash + +### DONT OVERWRITE THIS FILE + +app_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." &> /dev/null && pwd) + + +### GENERAL + + +project_name='www.domain.de' +shopware_version='6' + + +### STAGE + + +stage_use_git='y' # if the stage system is deployed using git + +stage_ssh_user='your-user' +stage_ssh_domain='your-domain' +stage_ssh_has_key_file='y' +stage_ssh_key_file='/path/to/.ssh/key' + +stage_httpdocs_path='/var/www/vhosts/domain.de/httpdocs' +stage_httpdocs_slug='/shopware' # optional slug if you install the software not directly in httpdocs + +stage_database_has_socket='n' +stage_database_socket='' +stage_database_host='localhost' +stage_database_port='3306' +stage_database_name='database_name' +stage_database_user='database_user' +stage_database_password='database_password' + +# only needed if you want to create a database +stage_database_admin_user='' +stage_database_admin_password='' + + +### LIVE + + +live_use_git='y' + +live_ssh_user='user' +live_ssh_domain='domain.de' +live_ssh_has_key_file='n' +live_ssh_key_file='' + +live_httpdocs_path='/var/www/vhosts/domain.de/httpdocs' +live_httpdocs_slug='' + +live_database_has_socket='n' +live_database_socket='' +live_database_host='localhost' +live_database_port='3306' +live_database_name='name' +live_database_user='user' +live_database_password='password' + +# only needed if you want to create a database +live_database_admin_user='' +live_database_admin_password='' + + +### LOCAL STAGE + + +local_stage_use_git='y' # if you don't work with the git working copy / you can sync local htdocs/. with git repo +local_stage_slug='/shopware' + +local_stage_database_has_socket='n' +local_stage_database_socket='' +local_stage_database_host='localhost' +local_stage_database_port='3306' +local_stage_database_name='name_stage' +local_stage_database_user='user' +local_stage_database_password='password' + +# only needed if you can't create database and want to create a database +local_stage_database_admin_user='' +local_stage_database_admin_password='' + + +### LOCAL LIVE + + +local_live_use_git='y' +local_live_slug='/shopware' + +local_live_database_has_socket='n' +local_live_database_socket='' +local_live_database_host='localhost' +local_live_database_port='3306' +local_live_database_name='name_live' +local_live_database_user='user' +local_live_database_password='password' + +# only needed if you can't create database and want to create a database +local_live_database_admin_user='' +local_live_database_admin_password='' + + +### SHOPWARE USER + + +local_shopware_user='user' +local_shopware_email='email' +local_shopware_firstname='Name' +local_shopware_lastname='Lastname' + + +### GIT + + +git_has_ssh_key_file='n' +git_ssh_key_file='' +git_url='' + +# you can update stage with data from live +live_to_stage_live_urls=("https://www.domain.de") +live_to_stage_stage_urls=("https://stage.domain.de") + +# if you copy the stage state to local +stage_to_local_stage_urls=("https://stage.domain.de") +stage_to_local_local_urls=("https://localhost/domain.de/stage.domain.de") + +# here more complete, copy the live system to local +live_to_local_live_urls=( + "http://www.domain.de" + "https://www.domain.de" +) +live_to_local_local_urls=( + "http://localhost/martins-domain.de/www.domain.de" + "https://localhost/domain.de/www.domain.de" +) + + +### GDPR SHOPWARE 6 TABLES + + +gdpr_tables=( + acl_user_role + cart + customer + customer_address + customer_recovery + customer_tag + customer_wishlist + customer_wishlist_product + elasticsearch_index_task + import_export_log + integration + integration_role + log_entry + message_queue_stats + newsletter_recipient + newsletter_recipient_tag + order + order_address + order_customer + order_delivery + order_delivery_position + order_line_item + order_tag + order_transaction + product_export + product_review + promotion_persona_customer + refresh_token + sales_channel_api_context + state_machine_history + user + user_access_key + user_config + user_recovery + version + version_commit + version_commit_data + klarna_payment_request_log + payone_payment_card + payone_payment_mandate + payone_payment_redirect + unzer_payment_payment_device + unzer_payment_transfer_info + enqeueue + product_keyword_dictionary + product_search_keyword +) + + +### POST SCRIPT + + +if [ -f "$app_dir/bin/post_config.sh" ] +then + source "$app_dir/bin/post_config.sh" +fi diff --git a/.etc/live.my.cnf b/.etc/live.my.cnf new file mode 100644 index 0000000..634f540 --- /dev/null +++ b/.etc/live.my.cnf @@ -0,0 +1,4 @@ +[mysqldump] +user= +password= +max_allowed_packet=500M diff --git a/.etc/local.my.cnf b/.etc/local.my.cnf new file mode 100644 index 0000000..95eadd5 --- /dev/null +++ b/.etc/local.my.cnf @@ -0,0 +1,9 @@ +[mysql] +user= +password= +max_allowed_packet=500M + +[mysqldump] +user= +password= +max_allowed_packet=500M diff --git a/.etc/stage.my.cnf b/.etc/stage.my.cnf new file mode 100644 index 0000000..634f540 --- /dev/null +++ b/.etc/stage.my.cnf @@ -0,0 +1,4 @@ +[mysqldump] +user= +password= +max_allowed_packet=500M diff --git a/.gitignore b/.gitignore index aedd43b..bdcd697 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .idea - +.ssh +backup +bin/postscripts +etc +var !.keep \ No newline at end of file diff --git a/.ssh/.keep b/.ssh/.keep new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index 1f236de..acbdda6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,36 @@ -# sw6-project-setup +# Project -Ein für Shopware 6 vorbereitet Systemmanagment. \ No newline at end of file +This are the most stable parts of the project manager, stay tuned... + +## Installation + +- First copy files from ".etc" to "etc" +- Configure etc files +- Start manager + + + bin/manager + +## Modify + +Replace {script-name} with the name of the script wich is located in bin/commands + + etc/post_config.sh + bin/postscripts/{script_name}.sh + +## Commands + +### Import Database + + Usage: import_db.sh [live|stage] + +### Make changes to the new local database (URL's and Admin-User) + + Usage: make_local_database.sh [live|stage] + +### Import media files + + Usage: import_media.sh [live|stage] /path/to/files + + import_media.sh stage /files + import_media.sh stage /public/media \ No newline at end of file diff --git a/backup/database/.keep b/backup/database/.keep new file mode 100644 index 0000000..e69de29 diff --git a/bin/commands/import_db.sh b/bin/commands/import_db.sh new file mode 100755 index 0000000..837f55f --- /dev/null +++ b/bin/commands/import_db.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +source "$(dirname "${BASH_SOURCE[0]}")/../includes/includes.sh" +app_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." &> /dev/null && pwd) +source "$app_dir/etc/config.sh" + +usage="Usage: import_db.sh [live|stage]" +env=$(getArgument $1 "$usage" "live stage") +currentDate=$(date '+%Y-%m-%d_%H:%M:%S') + +addSSHKey "$env" +ssh_user="$(eval "echo \$${env}_ssh_user")" +ssh_domain="$(eval "echo \$${env}_ssh_domain")" + +ignoredTablesArguments=$(buildIgnoredTablesArguments "$env" "${gdpr_tables[*]}") + +echo "Fetching Database ..." + +database_name=$(eval "echo \$${env}_database_name") +local_database_name=$(eval "echo \"\$local_${env}_database_name\"") + +scp "$app_dir/etc/$env.my.cnf" "$ssh_user"@"$ssh_domain":"~/$env.my.cnf" +ssh "$ssh_user"@"$ssh_domain" "mysqldump --defaults-extra-file=~/$env.my.cnf --no-tablespaces --no-data \ + \"$database_name\" | LANG=C LC_CTYPE=C LC_ALL=C sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | \ + sed -e 's/,NO_AUTO_CREATE_USER//' | gzip -9 > ~/${env}_structure.sql.gz" +scp "$ssh_user"@"$ssh_domain":"~/${env}_structure.sql.gz" "$app_dir/var/tmp/${env}_structure.sql.gz" +ssh "$ssh_user"@"$ssh_domain" "unlink ~/${env}_structure.sql.gz" +ssh "$ssh_user"@"$ssh_domain" "mysqldump --defaults-extra-file=~/${env}.my.cnf --no-tablespaces --no-create-info \ + --skip-triggers $ignoredTablesArguments \"$database_name\" | LANG=C LC_CTYPE=C LC_ALL=C \ + sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | gzip -9 > ~/${env}_data.sql.gz" +scp "$ssh_user"@"$ssh_domain":"~/${env}_data.sql.gz" "$app_dir/var/tmp/${env}_data.sql.gz" +ssh "$ssh_user"@"$ssh_domain" "unlink ~/${env}_data.sql.gz" +ssh "$ssh_user"@"$ssh_domain" "unlink ~/${env}.my.cnf" + +echo "Backup Database ..." + +mysqldump --defaults-extra-file="$app_dir/etc/local.my.cnf" --no-tablespaces --hex-blob --no-data "$local_database_name" | \ + LANG=C LC_CTYPE=C LC_ALL=C sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | sed -e 's/,NO_AUTO_CREATE_USER//' | gzip -9 > \ + "$app_dir/backup/database/${currentDate}_local_${env}_structure.sql.gz" + +mysqldump --defaults-extra-file="$app_dir/etc/local.my.cnf" --no-tablespaces --no-create-info --skip-triggers --hex-blob "$local_database_name" | \ + LANG=C LC_CTYPE=C LC_ALL=C sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | gzip -9 > \ + "$app_dir/backup/database/${currentDate}_local_${env}_data.sql.gz" + +cp "$app_dir/var/tmp/${env}_structure.sql.gz" "$app_dir/backup/database/${currentDate}_${env}_structure.sql.gz" +cp "$app_dir/var/tmp/${env}_data.sql.gz" "$app_dir/backup/database/${currentDate}_${env}_data.sql.gz" + +echo "Uncompress Database ..." +gzip --force -d "$app_dir/var/tmp/${env}_structure.sql.gz" +gzip --force -d "$app_dir/var/tmp/${env}_data.sql.gz" + +echo "Install Database ..." + +mysql --defaults-extra-file="$app_dir/etc/local.my.cnf" -e "CREATE DATABASE IF NOT EXISTS \`$local_database_name\`;" + +echo "Remove Tables ..." +mysqldump --defaults-extra-file="$app_dir/etc/local.my.cnf" --add-drop-table --add-drop-trigger --no-data "$local_database_name" | \ + grep -e '[DROP TABLE|DROP TRIGGER]' >> "$app_dir/var/tmp/drop_local_$env.sql" +echo "SET FOREIGN_KEY_CHECKS = 1;" >> "$app_dir/var/tmp/drop_local_$env.sql" +mysql --defaults-extra-file="$app_dir/etc/local.my.cnf" -D "$local_database_name" < "$app_dir/var/tmp/drop_local_$env.sql" + +echo "Import Structure ..." +mysql --defaults-extra-file="$app_dir/etc/local.my.cnf" -D "$local_database_name" < "$app_dir/var/tmp/${env}_structure.sql" + +echo "Import Data ..." +mysql --defaults-extra-file="$app_dir/etc/local.my.cnf" -D "$local_database_name" < "$app_dir/var/tmp/${env}_data.sql" + +echo "Post Scripts ..." +postScript "$app_dir/bin/postscripts/import_db.sh" + +"$app_dir/bin/commands/make_local_database.sh" "$env" + +echo "Cleanup ..." + +rm "$app_dir/var/tmp/drop_local_$env.sql" +rm "$app_dir/var/tmp/${env}_structure.sql" +rm "$app_dir/var/tmp/${env}_data.sql" + +echo diff --git a/bin/commands/import_media.sh b/bin/commands/import_media.sh new file mode 100755 index 0000000..f14c8bb --- /dev/null +++ b/bin/commands/import_media.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +source "$(dirname "${BASH_SOURCE[0]}")/../includes/includes.sh" +app_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." &> /dev/null && pwd) +source "$app_dir/etc/config.sh" + +env=$(getArgument "$1" "Usage: import_media.sh [live|stage] /path/to/files" "live stage") +filepath=$(getArgument "$2" "Usage: import_media.sh [live|stage] /path/to/files" "/files /public/media") +addSSHKey "$env" +ssh_user="$(eval "echo \$${env}_ssh_user")" +ssh_domain="$(eval "echo \$${env}_ssh_domain")" +slug="$(eval "echo \"\$local_${env}_slug\"")" + +source="$(eval "echo \"\$${env}_httpdocs_path\$${env}_httpdocs_slug\$filepath/.\"")" +target="$app_dir/git/${project_name}${slug}${filepath}/." + +echo +echoMainTitle "Fetching $filepath files from $env" + +echo +echo "Fetch Files ..." +rsync -auvzqLK --delete "$ssh_user"@"$ssh_domain":"$source" "$target" + +postScript "$app_dir/bin/postscripts/import_media.sh" + +echo \ No newline at end of file diff --git a/bin/commands/make_local_database.sh b/bin/commands/make_local_database.sh new file mode 100755 index 0000000..c681681 --- /dev/null +++ b/bin/commands/make_local_database.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +source "$(dirname "${BASH_SOURCE[0]}")/../includes/includes.sh" +app_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." &> /dev/null && pwd) +source "$app_dir/etc/config.sh" + +usage="Usage: make_local_database.sh [live|stage]" +env=$(getArgument "$1" "$usage" "live stage") +local_database_name=$(eval "echo \"\$local_${env}_database_name\"") + +echo +echoMainTitle "Make Local Database" + +echo +echo "Perform Database Changes ..." + +live_urls=$(eval "echo \"\$${env}_to_local_${env}_urls\"") +local_urls=$(eval "echo \"\$${env}_to_local_local_urls\"") +for i in "${!live_urls[@]}" +do + mysql --defaults-extra-file="$app_dir/etc/local.my.cnf" -D "$local_database_name" -e \ + "UPDATE sales_channel_domain SET url = '${local_urls[$i]}' WHERE url = '${live_urls[$i]}'" +done + +script="$(eval "echo \"$app_dir/git/$project_name\$local_${env}_slug/bin/console\"")" + +"$script" user:create -a --email="$local_shopware_email" --firstName="$local_shopware_firstname" --lastName="$local_shopware_lastname" "$local_shopware_user" + +postScript "$app_dir/bin/postscripts/make_local_database.sh" + +echo diff --git a/bin/includes/includes.sh b/bin/includes/includes.sh new file mode 100644 index 0000000..bc2bc0c --- /dev/null +++ b/bin/includes/includes.sh @@ -0,0 +1,162 @@ +#!/bin/bash + +if [ true != ${includes_included:-false} ] +then + includes_included=true + + function echoMainTitle { + echo -e "\033[1;34m$1\033[0m" + } + + function echoSubTitle { + echo -e "\033[0;32m$1\033[0m" + } + + function echoSelect { + local select="$1" + local message="$2" + echo -e "\033[0;33m$select\033[0m $message" + } + + function echoError { + echo -e "\033[0;91m$1\033[0m" + } + + function getArgument { + local errmsg=$2 + local allow=${3:-false} + local var=$1 + + if [ "$allow" != false ] && [ "$(isAllowed "$var" "$allow")" == false ] + then + echo "$errmsg" >&2 + exit 1 + fi + + echo "$var" + } + + function isAllowed { + local var="$1" + local allow="$2" + local valid=true + + if [ "$allow" == true ] && [ "$var" == "" ] + then + valid=false + elif [ "$allow" != false ] && [ "$allow" != true ] + then + allow=($allow) + local found=false + for i in "${!allow[@]}" + do + if [ "${allow[$i]}" == "$var" ] + then + found=true + fi + done + if [ "$found" != true ] + then + valid=false + fi + fi + + echo $valid + } + + function readConsole { + local message="$1" + local errmsg="$2" + local allow=${3:-false} + + read -p "$message" var + + if [ "$(isAllowed "$var" "$allow")" == false ] + then + echo "$errmsg" >&2 + var=$(readConsole "$message" "$errmsg" "$allow") + fi + + echo "$var" + } + + function addSSHKey { + local env=$(getArgument "$1" "Usage: addSSHKey [live|stage|git]" "live stage git") + local ssh_key_file="$app_dir/.ssh/$env" + local has_ssh_key_file=$(eval "echo \"\$${env}_has_ssh_key_file\"") + + if [ "$has_ssh_key_file" == "y" ] + then + copySSHKeys "$env" + else + installSSHKey "$env" + fi + ssh-add "$ssh_key_file" + } + + function copySSHKeys { + local env=$(getArgument "$1" "Usage: copySSHKeys [live|stage|git]" "live stage git") + local has=$(eval "echo \$${env}_has_ssk_key_file") + local source=$(eval "echo \$${env}_ssh_key_file") + local target="$app_dir/.ssh/$env" + + if [ -f "$source" ] && [ ! -f "$target" ] + then + cp "$source" "$target" + chmod 0600 "$target" + else + echoError "Could not copy ssh key file" >&2 + exit 1 + fi + if [ -f "$source.pub" ] && [ ! -f "$target.pub" ] + then + cp "$source.pub" "$target.pub" + chmod 0600 "$target.pub" + else + echoError "Could not copy ssh key file" >&2 + exit 1 + fi + } + + function installSSHKey { + local env=$(getArgument "$1" "Usage: installSSHKey [live|stage|git]" "live stage git") + local has=$(eval "echo \"\$${env}_has_ssh_key_file\"") + local file=$(eval "echo \"\$${env}_ssh_key_file\"") + local user=$(eval "echo \"\$${env}_ssh_user\"") + local domain=$(eval "echo \"\$${env}_ssh_domain\"") + + if [ "$has" == "n" ] && [ ! -f "$app_dir/.ssh/$env"] + then + ssh-keygen -b 4096 -t rsa -f "$app_dir/.ssh/$env" -q -N "" + chmod 0600 "$app_dir/.ssh/$env" + chmod 0600 "$app_dir/.ssh/$env.pub" + + echo "Please enter SSH $env system password:" + ssh-copy-id -i "$app_dir/.ssh/$env.pub" "$user"@"$domain" + fi + } + + function buildIgnoredTablesArguments { + local env=$(getArgument "$1" "Usage: buildIgnoredTables [live|stage|local] [ignoredTablesArray]" "live stage local") + local ignoredTables=$(getArgument "$2" "Usage: buildIgnoredTables [live|stage|local] [ignoredTablesArray]" true) + + local database_name=$(eval "echo \"\$${env}_database_name\"") + + ignoredTables=($ignoredTables) + local ignoredTablesArguments="" + for table in "${ignoredTables[@]}" + do + ignoredTablesArguments="$ignoredTablesArguments --ignore-table=\"${database_name}.${table}\"" + done + + echo "$ignoredTablesArguments" + } + + function postScript { + local script=$(getArgument "$1" "Usage: postScript \"post_script.sh\"" true) + if [ -f "$script" ] + then + source "$script" + fi + } +fi diff --git a/bin/manager b/bin/manager new file mode 100755 index 0000000..32f2c6b --- /dev/null +++ b/bin/manager @@ -0,0 +1,104 @@ +#!/bin/bash + +set -e + +source "$(dirname "${BASH_SOURCE[0]}")/includes/includes.sh" +app_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." &> /dev/null && pwd) +source "$app_dir/etc/config.sh" + +echo +echoMainTitle "What do you want to do today?" + +echo +echoSelect "[1]" "Databaseupdate" +echoSelect "[2]" "Fetching Files" +echoSelect "[3]" "Fetching Public Media" +echo +main_selection=$(readConsole "Select: " "Invalid selection" "1 2 3") +words=( + 'databaseupdate' + 'files' + 'media' +) + +for i in "${!words[@]}" +do + ((cur=i+1)) + if [ $cur == "$main_selection" ] + then + main_selection=${words[$i]} + fi +done + +echo $main_selection + +if [ "$main_selection" == "databaseupdate" ] +then + echo + echoSubTitle "Databaseupdate" + echo + echo "From Environment:" + echo + echoSelect "[live] " "Live" + echoSelect "[stage] " "Stage" + echo + env=$(readConsole "Select: " "Invalid selection" "live stage") + + echo + confirm=$(readConsole "You want to copy the database from $env to local ($env)? [y,n]: " "Invalid selection" "y n") + + if [ "$confirm" == "y" ] + then + source "$app_dir/bin/commands/import_db.sh" "$env" + else + echo "Aborted" + fi +fi + +if [ "$main_selection" == "files" ] +then + echo + echoSubTitle "Fetching Files" + echo + echo "From Environment:" + echo + echoSelect "[live] " "Live" + echoSelect "[stage] " "Stage" + echo + env=$(readConsole "Select: " "Invalid selection" "live stage") + + echo + confirm=$(readConsole "You want to copy the /files from $env to local ($env)? [y,n]: " "Invalid selection" "y n") + + if [ "$confirm" == "y" ] + then + source "$app_dir/bin/commands/import_media.sh" "$env" "/files" + else + echo "Aborted" + fi +fi + +if [ "$main_selection" == "media" ] +then + echo + echoSubTitle "Fetching public Media" + echo + echo "From Environment:" + echo + echoSelect "[live] " "Live" + echoSelect "[stage] " "Stage" + echo + env=$(readConsole "Select: " "Invalid selection" "live stage") + + echo + confirm=$(readConsole "You want to copy the /public/media from $env to local ($env? [y,n]: " "Invalid selection" "y n") + + if [ "$confirm" == "y" ] + then + source "$app_dir/bin/commands/import_media.sh" "$env" "/public/media" + else + echo "Aborted" + fi +fi + +echo \ No newline at end of file diff --git a/bin/postscripts/.keep b/bin/postscripts/.keep new file mode 100644 index 0000000..e69de29 diff --git a/etc/.keep b/etc/.keep new file mode 100644 index 0000000..e69de29 diff --git a/git/.keep b/git/.keep new file mode 100644 index 0000000..e69de29