Commit e772d84a authored by Visay Keo's avatar Visay Keo

[IMP] Add more useful params with nicer message

parent a83acfa3
......@@ -4,6 +4,12 @@ CHANGELOG
3.0-dev
---------
-
3.0.0
-----
- [IMP] Add more useful params with nicer message
- [TASK] Update example in README
- [IMP] Add flow command resource:publish
......
......@@ -51,6 +51,10 @@ bin/syncontent -u=demo-014-007 -h=10.10.10.37 -p=/home/user/neosbox
- `-u` | `--remote-user` : Set the login user to the remote server (__Required__)
- `-h` | `--remote-host` : Set the hostname or IP address of the remote server (__Default__: `10.10.10.27`)
- `-p` | `--remote-path` : Set path to the document root on the remote server (__Default__: `/home/<remote-user>/public_html`)
- `-t` | `--ansible-tags`: Set the specific task you want run. See available sysc tasks section for details
- `-v` : Set the verbosity of ansible output. You can also set more verbose by adding more `v` like `-vvvvv`
- `--dry-run` : Force to display the command to execute but won't run them. Useful for debugging when you want
to see the full ansible command and maybe execute them directly for better error hints
### Customization
......@@ -94,6 +98,68 @@ directory. In case there are more than one file exists, the script will take fir
- In most case, the default host and path work fine for internal Web Essentials project development
and you just need to define the `--remote-user`
### Available Sync Tasks
Syncontent does its job in 3 different batches. First it sync the user files from remote server to local. Second it dumps
the database from remote and restore on local and last it runs some necessary flow commands for clean up.
By default, syncontent will run all 3 tasks but you can pass the parameter to call specific task only that you want to run.
```bash
bin/syncontent --ansible-tags=<TASK-NAME>
```
The available task names are:
- rsync
- db
- flow
### 1. rsync
The first task is to sync directory content in `Data/Persistent/` from remote to local. Files that exists only in local
will be removed to make sure everything is exactly the same as on remote.
To execute this task only, run the command:
```bash
bin/syncontent --ansible-tags=rsync
```
### 2. db
The second task is to reset the local database. It will start by connecting to remote server and get the database connection
information for the Production context of Flow. You cannot change to other context at the moment so if your remote is not
running in Production context, this tool won't work for you but anyway tweaking it to work is not that hard
and you can do it in the ansible role.
Once it gets all the information, it will dump the database, zip it and download to local temp. Before restoring to local
database, it first deletes the local database completely and recreate it again. This way assures that we have exact
state as on remote and prevent from any issues with the migration status.
To execute this task only, run this command:
```bash
bin/syncontent --ansible-tags=db
```
### 3. flow
The last step is to run some necessary commands needed in Flow for the application to work. They run in the following order:
- flow:cache:flush --force
- database:setcharset
- doctrine:migrate
- resource:publish
- node:repair
- cache:warmup
To execute this task only, run this command:
```bash
bin/syncontent --ansible-tags=flow
```
## Author
Visay Keo <visay@web-essentials.asia>
......
......@@ -4,4 +4,8 @@
remote_user: "{{ ssh_user }}"
roles:
- role: rsync
- role: database
\ No newline at end of file
tags: rsync
- role: database
tags: db
- role: flow
tags: flow
......@@ -50,19 +50,3 @@
- name: Restore local database from remote dump
local_action: shell bin/dockerflow run db mysql -h db -u root -proot {{ local_db_name.stdout }} < /tmp/{{ db_name.stdout }}.sql
chdir="{{ local_path }}"
- name: Execute ./flow database:setcharset
local_action: shell FLOW_CONTEXT={{ local_flow_context }} bin/dockerflow run app ./flow database:setcharset
chdir="{{ local_path }}"
- name: Execute ./flow flow:cache:flush --force
local_action: shell FLOW_CONTEXT={{ local_flow_context }} bin/dockerflow run app ./flow flow:cache:flush --force
chdir="{{ local_path }}"
- name: Execute ./flow cache:warmup
local_action: shell FLOW_CONTEXT={{ local_flow_context }} bin/dockerflow run app ./flow cache:warmup
chdir="{{ local_path }}"
- name: Execute ./flow resource:publish
local_action: shell FLOW_CONTEXT={{ local_flow_context }} bin/dockerflow run app ./flow resource:publish
chdir="{{ local_path }}"
Flow
====
Execute necessary flow commands to setup the system.
License
-------
MIT
Author Information
------------------
Visay Keo <visay@web-essentials.asia>
---
# defaults file for flow
---
# handlers file for flow
---
galaxy_info:
author: Visay Keo
description: Execute necessary flow commands to setup the system
company: Web Essentials
license: MIT
min_ansible_version: 1.6
platforms:
- name: Ubuntu
versions:
- trusty
dependencies: []
---
# tasks file for flow
- name: Remove PackageStates.php and temp caches directory
local_action: shell rm -rf Configuration/PackageStates.php Data/Temporary
chdir="{{ local_path }}"
- name: Execute neccessary flow commands
local_action: shell FLOW_CONTEXT={{ local_flow_context }} bin/dockerflow run app ./flow {{ item }}
chdir="{{ local_path }}"
with_items:
- flow:cache:flush --force
- database:setcharset
- doctrine:migrate
- resource:publish
- node:repair
- cache:warmup
---
# vars file for flow
......@@ -2,4 +2,7 @@
# tasks file for rsync
- name: Sync persistent data from remote server to local
synchronize: mode=pull src="{{ remote_path }}/Data/Persistent/" dest="{{ local_path }}/Data/Persistent/"
\ No newline at end of file
synchronize: mode=pull
src="{{ remote_path }}/Data/Persistent/"
dest="{{ local_path }}/Data/Persistent/"
delete=yes
......@@ -4,6 +4,15 @@
ROOT_DIR=`pwd`
PACKAGE_DIR="${ROOT_DIR}/Packages/Libraries/visay/syncontent"
# Colors
RED="\033[0;31m"
GREEN="\033[0;32m"
BROWN="\033[0;33m"
WHITE="\033[0;37m"
NC="\033[0m"
echo
# Read all arguments and parse into variable ${REMOTE_USER}, ${REMOTE_PATH} and ${REMOTE_HOST}
for ARGS in "$@"
do
......@@ -20,6 +29,18 @@ do
REMOTE_HOST="${ARGS#*=}"
shift
;;
-t=*|--ansible-tags=*)
ANSIBLE_TAGS="--tags=${ARGS#*=}"
shift
;;
-v*)
VERBOSE_LEVEL="${ARGS}"
shift
;;
--dry-run)
DRY_RUN="${ARGS}"
shift
;;
esac
done
......@@ -30,11 +51,14 @@ fi
# If remote user is not set anywhere, throw error
if [ -z "${REMOTE_USER}" ]; then
echo "Please specify the user of the remote server to sync from:"
echo "Example: bin/syncontent --remote-user=latest-014-007"
echo "Example: bin/syncontent -u=demo-014-007"
echo "Or specify it in config/master directory, read the doc"
exit 0
echo -e ${RED}"-> Please specify the user of the remote server to sync from:"${NC}
echo
echo -e ${BROWN}"Example: bin/syncontent --remote-user=latest-014-007"${NC}
echo -e ${BROWN}"Example: bin/syncontent -u=demo-014-007"${NC}
echo
echo -e ${BROWN}"Or specify it in config/master directory, read the doc"${NC}
echo
exit 1
fi
# Extract from the remote user to get the stage name
......@@ -43,10 +67,12 @@ STAGE=`echo ${REMOTE_USER} | cut -d '-' -f1`
# Check if stage is not latest or demo, throw error
if [ "${STAGE}" != "latest" ] && [ "${STAGE}" != "demo" ]; then
echo "Only latest or demo is supported at the moment:"
echo "Example: bin/syncontent -u=latest-014-007"
echo "Example: bin/syncontent --remote-user=demo-014-007"
exit 0
echo -e ${RED}"-> Only latest or demo is supported at the moment:"${NC}
echo
echo -e ${BROWN}"Example: bin/syncontent -u=latest-014-007"${NC}
echo -e ${BROWN}"Example: bin/syncontent --remote-user=demo-014-007"${NC}
echo
exit 1
fi
# If remote host is not set, read it from config file
......@@ -74,9 +100,11 @@ fi
# Test connection to the server whether auto login is enabled
PING=`ssh -q -o "BatchMode=yes" ${REMOTE_USER}@${REMOTE_HOST} echo "OK"`
if [ "${PING}" != "OK" ]; then
echo "Public key authentication failed!"
echo "Make sure you have auto login when running: ssh ${REMOTE_USER}@${REMOTE_HOST}"
exit 0
echo -e ${RED}"-> Public key authentication failed!"${NC}
echo
echo -e ${BROWN}"Make sure you have auto login when running: ${WHITE}ssh ${REMOTE_USER}@${REMOTE_HOST}"${NC}
echo
exit 1
fi
# If remote path is not set in argument, check for it in the configuration file
......@@ -96,29 +124,72 @@ if [ -z "${REMOTE_PATH}" ]; then
fi
fi
# If remote path is defined anywhere, set a standard value
# If remote path is not defined anywhere, set a standard value
if [ -z "${REMOTE_PATH}" ]; then
REMOTE_PATH="/home/${REMOTE_USER}/public_html"
fi
# Check if persistent directory exists at the remote path on the server
if (ssh ${REMOTE_USER}@${REMOTE_HOST} "[ ! -d ${REMOTE_PATH}/Data/Persistent ]"); then
echo "Directory '${REMOTE_PATH}/Data/Persistent' does not exist on the server"
echo "Check if your '--remote-path' config is set properly"
exit 0
echo -e ${RED}"-> Directory '${REMOTE_PATH}/Data/Persistent' does not exist on the server"${NC}
echo
echo -e ${BROWN}"Check if your '--remote-path' config is set properly"${NC}
echo
exit 1
fi
# Use Development context if Flow Context is not set
FLOW_CONTEXT=${FLOW_CONTEXT:=Development}
echo "Start content sync from ${REMOTE_USER} (Production context)"
echo " to local docker in (${FLOW_CONTEXT} context)"
echo -e ${GREEN}"ENVIRONMENT SUMMARY:"${NC}
echo "====================="
echo -e "FROM: ${GREEN}${REMOTE_USER}${NC}"
echo -e "CONTEXT: ${GREEN}Production${NC}"
echo "---------------------"
echo -e "TO: ${GREEN}Local Docker${NC}"
echo -e "CONTEXT: ${GREEN}${FLOW_CONTEXT}${NC}"
echo "---------------------"
echo
if [[ -n "${DRY_RUN}" ]]; then
echo -e ${GREEN}"DRY RUN MODE:"${NC}
echo "============"
echo
echo -e ${BROWN}"The following command should be executed"${NC}
echo "----------------------------------------"
echo "ansible-playbook -i ${PACKAGE_DIR}/ansible/hosts.ini ${PACKAGE_DIR}/ansible/playbook.yml ${VERBOSE_LEVEL} ${ANSIBLE_TAGS} --extra-vars \"stage=${STAGE} ssh_user=${REMOTE_USER} local_path=${ROOT_DIR} remote_path=${REMOTE_PATH} local_flow_context=${FLOW_CONTEXT}\""
echo
exit 0
fi
ansible-playbook -i ${PACKAGE_DIR}/ansible/hosts.ini ${PACKAGE_DIR}/ansible/playbook.yml \
--extra-vars "stage=${STAGE}
ssh_user=${REMOTE_USER}
local_path=${ROOT_DIR}
remote_path=${REMOTE_PATH}
local_flow_context=${FLOW_CONTEXT}"
# Ask user to confirm
read -p "Are you sure (y/n)? " -r
echo
if [[ ! ${REPLY} =~ ^[Yy]$ ]]; then
echo -e ${BROWN}"#############################"
echo "### CONTENT SYNC SKIPPED ###"
echo -e "#############################"${NC}
exit 0
fi
echo "Sync content from ${STAGE} completed!"
echo -e ${GREEN}"#############################"
echo "### STARTING CONTENT SYNC ###"
echo -e "#############################"${NC}
ansible-playbook -i ${PACKAGE_DIR}/ansible/hosts.ini ${PACKAGE_DIR}/ansible/playbook.yml ${VERBOSE_LEVEL} ${ANSIBLE_TAGS} \
--extra-vars "stage=${STAGE} ssh_user=${REMOTE_USER} local_path=${ROOT_DIR} remote_path=${REMOTE_PATH} local_flow_context=${FLOW_CONTEXT}" \
|| ERROR="1"
if [[ -n "${ERROR}" ]]; then
echo
echo -e ${RED}"-> Ansible argument error"${NC}
echo
echo -e ${BROWN}"Please make sure you pass the correct parameters"
echo -e "Read the documentation for detailed usage"${NC}
echo
exit 1
else
echo -e ${GREEN}"#############################"
echo "### CONTENT SYNC COMPLETE ###"
echo -e "#############################"${NC}
fi
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment