├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── LICENSE ├── README.md ├── VERSION ├── bin ├── dsh └── dsh-bash-complete ├── docker-compose.yml ├── docs ├── apache-solr.md ├── behat.md ├── blackfire.md ├── custom-commands.md ├── db-access.md ├── db-sandbox.md ├── dde-env-setup.md ├── dde-project-setup.md ├── directory-structure.md ├── drupal-settings.md ├── img │ ├── behat-behat-yml.png │ ├── behat-phpstorm-PHP-Behat-configuration.png │ ├── behat-phpstorm-PHP-configuration-deployment.png │ ├── behat-phpstorm-PHP-configuration.png │ ├── behat-phpstorm-deployment-configure-mapping.png │ ├── behat-phpstorm-deployment-configure.png │ ├── behat-run-debug-configuration.png │ ├── behat-run-tests.png │ ├── behat-run-window.png │ ├── behat-selenium-container.png │ ├── behat-test-features.png │ ├── unionfs-container.png │ ├── unionfs-your-image.png │ ├── xdebug-mapping.png │ ├── xdebug-toggle-debugger.png │ └── xdebug-toggle-listener.png ├── mail.md ├── multiple-projects.md ├── phpcs.md ├── public-access.md ├── sass.md ├── settings.md ├── ssh-agent.md ├── system-requirements.md ├── troubleshooting.md ├── varnish.md └── xdebug.md ├── examples └── .drude │ ├── commands │ ├── init │ └── phpcs │ └── etc │ ├── mysql │ └── my.cnf │ └── php5 │ ├── php-cli.ini │ └── php.ini └── tests ├── README.md ├── basics_check_functions.bats ├── control_functions.bats ├── drush.bats ├── dsh_script.bash ├── exec.bats ├── helper_functions.bats ├── helpers └── helper.bash ├── init.bats ├── reset.bats ├── restart.bats ├── run-tests.sh ├── ssh-add.bats ├── ssh-key ├── bats_rsa └── bats_rsa.pub ├── start.bats ├── status.bats ├── stop.bats ├── troubleshooting.bats └── update.bats /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE files 2 | .idea 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tests/helpers/bats-support"] 2 | path = tests/helpers/bats-support 3 | url = https://github.com/ztombol/bats-support.git 4 | [submodule "tests/helpers/bats-assert"] 5 | path = tests/helpers/bats-assert 6 | url = https://github.com/ztombol/bats-assert.git 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 1.6.0 (2016-10-24) 4 | 5 | - Drude is now DDE (Drupal Development Environment) 6 | - DDE is retired in favor of [Docksal](https://github.com/docksal/docksal) 7 | 8 | 9 | ## 1.5.1 (2016-10-17) 10 | 11 | - Fix dsh mysql commands 12 | 13 | 14 | ## 1.5.0 (2016-10-10) 15 | 16 | IMPORTANT: Please run `dsh update images` after updating to this release. 17 | 18 | - Refactored ssh-add and fixed issues on Windows 19 | - Bats tests for Drude 20 | - Fixes for installation on Ubuntu 21 | - Use standard docker.sock location with vhost-proxy service 22 | - Removed references to `console.exe` (old winpty version) on Windows - this fixes `dsh bash` on older installations 23 | - Docs 24 | - Added Sass docs 25 | - Added blackfire.io docs 26 | - Updated mailhog docs (now with a permanent approach) 27 | - Updated xdebug docs (using xdebug with console scripts, e.g. drush) 28 | - Updated Behat docs (additional info about Behat configuration) 29 | - Moved license to a separate file 30 | - Retirement announcement 31 | 32 | 33 | ## 1.4.1 (2016-07-01) 34 | 35 | - Hotfixes 36 | - Addressed an issue with php5 vs php7 supervisord service name 37 | - Account that winpty executable was renamed in 0.3.0 to "winpty.exe" 38 | - Added ability to stop Drude system containers with dsh 39 | - Stop docker daemon before running prerequsite updates on Ubuntu to prevent client-server difference error 40 | - Documentation updates 41 | - Massive updates to [Behat docs](docs/behat.md) 42 | - PHPStorm integration 43 | - Use hosts's Selenium server and browsers 44 | - phpcs docs updates 45 | 46 | 47 | ## 1.4.0 (2016-06-10) 48 | 49 | - dsh v1.20.0 50 | - Added update checker (once a week, currently dsh only) 51 | - Allow install prerequisites on other Linux versions if user takes the risk 52 | - dsh -v will now show short version 53 | - New command `dsh system-info` for debugging purposes 54 | - System-wide services 55 | - New service: `ssh-agent`. See [ssh-agent docs](docs/ssh-agent.md) for more details. 56 | - Bind system-wide services to 0.0.0.0 for simplicity 57 | - `dsh reset` can now install/reset system-wide services (dns, vhost-proxy, ssh-agent) 58 | - Support for [custom commands](docs/custom-commands.md) in dsh 59 | - Support for overlay networks for vhost-proxy (v2 compose file format) 60 | - Other improvements 61 | - dsh remove -f to quietly remove containers 62 | - Support dsh reset -f to quietly reset containers 63 | - Documentation updates 64 | - [Docs](docs/apache-solr.md) for Apache Solr 65 | - [Docs](docs/settings.md) on switching PHP and MySQL versions 66 | - Many other small updates and fixes 67 | 68 | 69 | ## 1.3.4 (2016-05-04) 70 | 71 | - dsh v1.13.3 72 | - Fix regression with is_docker_running check in boot2docker 73 | 74 | A full update is recommended. Please follow the updates instructions: 75 | https://github.com/blinkreaction/drude#updates 76 | 77 | 78 | ## 1.3.3 (2016-04-29) 79 | 80 | - dsh v1.13.2 81 | - Fix regression with dsh behat 82 | 83 | A full update is recommended. Please follow the updates instructions: 84 | https://github.com/blinkreaction/drude#updates 85 | 86 | 87 | ## 1.3.2 (2016-04-26) 88 | 89 | - dsh v1.13.1 90 | - Fix regression with docker-compose related function calls introduced in dsh v1.13.0 91 | - Documentation fixes 92 | 93 | A full update is recommended. Please follow the updates instructions: 94 | https://github.com/blinkreaction/drude#updates 95 | 96 | 97 | ## 1.3.1 (2016-04-21) 98 | 99 | - A lot of refactoring to bring interactive shell experience to Windows (via winpty, which is a requirement now on Windows) 100 | - `dsh update boot2docker` will now ask for a confirmation 101 | - `dsh exec` (`dsh run`) can now run interactive commands (try `dsh exec top`) 102 | - `dsh bash` now longer relies on `vagrant ssh -c` and thus launches much faster 103 | - `dsh mysql-import` now disaplays a progress via `pv` (same as on Mac/Linux) 104 | - Fixed `dsh bash`regression from v1.3.0 on Mac/Linux 105 | - Documentation fixes and updates 106 | 107 | A full update is recommended. Please follow the updates instructions: 108 | https://github.com/blinkreaction/drude#updates 109 | 110 | 111 | ## 1.3.0 (2016-04-15) 112 | 113 | - Implement dsh drupal shortcut for Drupal Console commands 114 | - dsh bash improved on Windows 115 | - Use winpty on Windows (if installed), fall back to "vagrant ssh" otherwise 116 | - Make sure Docker TLS is disabled 117 | - Refactored of install/update commands 118 | - Refactored of docker daemon status check on different platforms 119 | - Automatic detection of host user id 120 | - Docker user id in cli is matched to the host user id 121 | - Add messaging that running as root is not recommended 122 | - Fixed the issue with line breaks when running dsh stop 123 | - Fixed dsh drush (with no arguments) throws an error message 124 | - Documentation updates 125 | - Added MailHog service usage instructions 126 | - Added Varnish service usage instructions 127 | - Misc update and typo fixes 128 | 129 | 130 | ## 1.2.4 (2016-01-20) 131 | 132 | - Bump dsh to v1.10.3 133 | - Fixed "tput: No value for $TERM and no -T specified" in noninteractive (CI) environments 134 | - Fixed "Error response from daemon: no such id: bash" on Windows 135 | - Restructured and updated docs with setup instructions per use case 136 | 137 | ## 1.2.3 (2015-12-04) 138 | 139 | - Bump dsh to v1.9.3 140 | - Fix in _set_cli_uid for non-interactive sessions 141 | 142 | ## 1.2.2 (2015-12-04) 143 | 144 | - Fix a really tiny typo in the README. 145 | - Bump dsh to v1.9.2 146 | - Fix DRUDE_SET_UID usage (experimental) when combined with DRUDE_DC_PROJECT. 147 | 148 | ## 1.2.1 (2015-11-17) 149 | 150 | - Droped /cygdrive prefix on Windows 151 | - Compatibility fix for the new docker-compose binary on Windows in boot2docker-vagrant v1.3.0+ 152 | - Fixed Ubuntu version check 153 | - Updated minimal versions requirements 154 | 155 | ## 1.2.0 (2015-11-11) 156 | 157 | - Ubuntu support 158 | - Added docker-compose installation 159 | - Point dns service to 8.8.8.8 to prevent it from recursing to itself 160 | - Allow to override the user id in the cli container via DRUDE_SET_UID environment variable 161 | - Experimental. Requires `blinkreaction/drupal-cli:latest` 162 | - Fixed #65 (`dsh stop --all` should not stop system containers) 163 | - Docs updates 164 | - MySQL DB access for external tools 165 | - Updated minimal versions requirements 166 | 167 | ## 1.1.0 (2015-10-26) 168 | 169 | Notable changes: 170 | 171 | - Lots of dsh updates 172 | - `dsh remove` can now remove a single container 173 | - `dsh stop --all` will stop all running containers 174 | - `dsh restart` command now restarts only containers 175 | - `dsh reset` can reset individual container 176 | - `dsh logs` command will display all/individual container logs 177 | - `dsh vmstat` command will show VirtualBox VM stats 178 | - `dsh exec-url` command will download a script from a URL and run it 179 | - `dsh behat` now access a `--path=` option 180 | - `dsh install prerequisites` now supports Ubuntu 14.04+ 181 | - docker-compose.yml 182 | - BIG CHANGE: PHP is now solely in the CLI container (single place for cli and web). Web container has Apache only and uses php-fpm service in CLI. 183 | - Added Solr container example 184 | - DOMAIN_NAME environment variable can now be used for service discovery between containers (instead of docker links). Using this will memcached, browser and solr nodes. 185 | - Using stable tags for web (blinkreaction/drupal-apache:2.2-stable) and cli (blinkreaction/drupal-cli:stable) 186 | - Documentation updates 187 | - Updated docs on D7 and D8 settings (including reverse proxy settings for vhost-proxy) 188 | - Updated Behat instructions 189 | - Added Drupal 8 sample project link 190 | - Miscellaneous 191 | - Removed CircleCI stuff. It has not been used in a while and is outdated 192 | - Changed default docker host to 192.168.10.10:2375 (private network interface) instead of 127.0.0.1:2375 (NAT) for better performance of the docker client with VBox's Intel adapters 193 | - Added error reporting php settings in [examples/.drude/etc/php5](examples/.drude/etc/php5) 194 | 195 | ## 1.0.1 (2015-09-14) 196 | 197 | - Bump dsh version to v1.0.1 198 | 199 | ## 1.0.0 (2015-09-14) 200 | 201 | - Properly handle complex parameters in `dsh drush` 202 | - Bash autocomplete for dsh 203 | - Support running drush with symlinked directories 204 | - Host's home directory mapping in CLI container to simplify mounts for SSH keys and other credentials and configs. 205 | - Support for custom SSH key names 206 | - Debugging with Xdebug tutorial 207 | - Documentation cleanup and updates (php and mysql settings overrides, vhost-proxy usage, troubleshooting docs) 208 | 209 | ## 1.0.0-rc1 (2015-08-26) 210 | 211 | - Switching shell scripts back to /bin/bash for consistency across all platforms 212 | - Added support for `dsh bash ` 213 | - Support for import of gzipped DB dumps in `dsh mysql-import` command 214 | - `dsh reset` now removes container volumes 215 | - Mount both .ssh folder options (Linux and B2D) for `cli` 216 | - Complete overhaul of the install/update process 217 | - `dsh install prerequisites`, `dsh install boot2docker`, `dsh install drude` commands for Mac and Windows 218 | - Use **Babun Shell** instead of **Git Bash** on Windows 219 | - Get rid of the dsh wrapper script - install dsh directly 220 | - Abandon git based install method. Remove git repository requirement 221 | - Repo structure overhaul. Only `docker-compose.yml` is installed into a project repo 222 | - `dsh update`: make sure `~/.drude exists`, otherwise config backups will fail 223 | - Removed obsolete scripts 224 | - Added `dsh version` and `dsh self-update` commands 225 | - Added `dsh init` command (calls .drude/scripts/drude-init.sh) 226 | - Added `.drude/scripts/example.drude-init.sh` script 227 | - `dsh init` can accept a URL argument for the `drude-init.sh` script 228 | - `dsh drush` functions now works even outside of the docroot 229 | - Proper handling of non-interactive shells 230 | - Switching to php5.6 for both `web` and `cli` 231 | - Switching containers to non-conflicting port mode - using vhost-proxy 232 | - Instructions for configuring *.drude wildcard DNS resolution on Mac 233 | - Use a helper function to call docker-compose and pass file and project arguments 234 | - Support for defining a Drude and boot2docker-vagrant branch for testing purposes via environment variables (`DRUDE_BRANCH`, `B2D_BRANCH`) 235 | - Refactor `_run` command. cmdpath is not needed anymore 236 | - Fix cli php config path 237 | - Automatically configure `DOCKER_HOST` on Mac and Windows (on every dsh call), skip on Linux 238 | - Workaround for `dsh bash` on Windows via `vagrant ssh -c` 239 | - Hidden (dev-only) `dsh remove` command 240 | - Mac only: desktop notification when mysql import has finished 241 | - Other miscellaneous fixes and improvements 242 | - Documentation updates 243 | 244 | ## 0.12.0 (2015-04-07) 245 | 246 | - Added "browser" node for Behat tests requiring JS support 247 | - Documented using Behat 248 | - CI: circle.docker-compose.yml us now used for automated tests of Drude, while docker-compose.yml is still the one packaged for distribution. This is not ideal... Need to figure out a way to alter docker-compose.yml during the build to comment out sections used in Drude's own CI tests, but optional for end users. 249 | 250 | ## 0.11.0 (2015-03-27) 251 | 252 | - Drude Shell (dsh) tool - an all-in-one tool for daily Drude use 253 | - New build and release process 254 | - Using semantic versioning and tracking changes in the CHANGELOG.md file 255 | - CircleCI integration for automated testing and build purposes 256 | - New install and update process 257 | - Documentation overhaul 258 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2015-2016 Blink Reaction 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DDE (**D**rupal **D**ocker **E**nvironment) 2 | 3 | Docker and Docker Compose based environment for Drupal. 4 | 5 | ------------------------- IMPORTANT ANNOUNCEMENT ------------------------- 6 | 7 | As of October 24th 2016 **this project is retired**. 8 | Existing users may continue using it as-is but are advised to switch to [Docksal](https://github.com/docksal/docksal). 9 | Docksal has lots of improvements, new features and less complex setup (no more Vagrant involved). 10 | [How to upgrade from Drude to Docksal](http://docksal.readthedocs.io/en/master/getting-started/upgrade-dde) 11 | 12 | -------------------------------------------------------------------------- 13 | 14 | 15 | **For a fully working example of DDE setup take a look at:** 16 | - [Drupal 7 sample project](https://github.com/blinkreaction/drude-d7-testing) 17 | - [Drupal 8 sample project](https://github.com/blinkreaction/drude-d8-testing) 18 | 19 | 20 | ## System requirements 21 | 22 | Please review [system requirements](/docs/system-requirements.md) before proceeding with the setup. 23 | 24 | 25 | 26 | ## Setup 27 | 28 | 1. [DDE environment setup](/docs/dde-env-setup.md) 29 | 30 | This is done **one time per host** and should be performed by everyone. 31 | 32 | 2. [Configure a project to use DDE](/docs/dde-project-setup.md) 33 | 34 | This is done **one time per project** and should be performed by the project TL. 35 | 36 | 37 | 38 | ## Updates 39 | 40 | Switch to your `` folder and run: 41 | 42 | ``` 43 | dsh self-update 44 | dsh update prerequisites 45 | ``` 46 | 47 | On Mac and Windows only (skip for Linux) also run: 48 | 49 | ``` 50 | dsh update boot2docker 51 | ``` 52 | 53 | Finally, you will probably need to re-initialize your environment with: 54 | 55 | ``` 56 | dsh init 57 | ``` 58 | 59 | 60 | 61 | ## DDE Shell Helper (dsh) 62 | 63 | DDE shell helper is a console tool that simplifies day-to-day work with DDE. 64 | It provides a set of most commonly used commands and operations for controlling the Boot2docker VM, containers, running drush or other commands inside the **cli** container. (**Note**: dsh requires cli container to function properly) 65 | 66 | See `dsh help` for a complete list. 67 | 68 | `dsh` detects the environment it's launched in and will automatically start the boot2docker VM and launch containers as necessary. 69 | It runs on Mac/Linux directly. On Windows `dsh` runs inside the Babun Shell. 70 | 71 | 72 | 73 | ## Console tools (cli) 74 | 75 | The **cli** container is meant to serve as a single console to access all necessary command line tools. 76 | You can access **cli** container's console with `dsh`: 77 | 78 | ``` 79 | dsh bash 80 | ``` 81 | 82 | Tools available inside the **cli** container: 83 | 84 | - php-cli, composer, drush[6,7,8], drupal console, phpcs, phpcbf 85 | - ruby, bundler 86 | - node, nvm, npm 87 | - imagemagick 88 | - python, git, mc, mysql-client and [more](https://github.com/blinkreaction/docker-drupal-cli) 89 | 90 | 91 | 92 | ## Instructions and tutorials 93 | 94 | ### Advanced configuration 95 | - [Drupal settings](/docs/drupal-settings.md) 96 | - [Overriding default PHP/MySQL/etc. settings](/docs/settings.md) 97 | - [Running multiple projects](/docs/multiple-projects.md) 98 | - [DB sandbox mode](/docs/db-sandbox.md) 99 | - [MySQL DB access for external tools](/docs/db-access.md) 100 | - [Extending dsh with custom commands](/docs/custom-commands.md) 101 | 102 | ### Third party utililies 103 | - [Debugging with Xdebug and PhpStorm](/docs/xdebug.md) 104 | - [Using PHP Code Sniffer (phpcs, phpcbf)](/docs/phpcs.md) 105 | - [Using Blackfire profiler](/docs/blackfire.md) 106 | - [Public access via ngrok](/docs/public-access.md) 107 | - [Using Behat](/docs/behat.md) 108 | - [Sending and capturing e-mail](/docs/mail.md) 109 | - [Enabling Varnish support](/docs/varnish.md) 110 | - [Enabling Apache Solr support](/docs/apache-solr.md) 111 | - [Using Sass](/docs/sass.md) 112 | - [Using custom ssh keys (with or without passwords) via ssh-agent](/docs/ssh-agent.md) 113 | 114 | 115 | ## Troubleshooting 116 | 117 | See [Troubleshooting](/docs/troubleshooting.md) section of the docs. 118 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 1.6.0 -------------------------------------------------------------------------------- /bin/dsh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DSH_VERSION=1.21.2 4 | 5 | # Console colors 6 | red='\033[0;91m' 7 | red_bg='\033[101m' 8 | green='\033[0;32m' 9 | green_bg='\033[42m' 10 | yellow='\033[1;33m' 11 | NC='\033[0m' 12 | 13 | #---------------------------- Global Constants -------------------------------- 14 | # Configuration path 15 | DRUDE_CONFIG_DIR="$HOME/.drude" 16 | DRUDE_CONFIG_BACKUP_DIR="$DRUDE_CONFIG_DIR/backups" 17 | # Always try to create this path in case ~/.drude does not exist 18 | mkdir -p $DRUDE_CONFIG_BACKUP_DIR 19 | 20 | DRUDE_LAST_CHECK="$DRUDE_CONFIG_DIR/last_check" 21 | DRUDE_B2D_VERSION="$DRUDE_CONFIG_DIR/b2d_version" 22 | 23 | # Where custom commands live 24 | DRUDE_COMMANDS_PATH=".drude/commands" 25 | 26 | # Network settings 27 | DRUDE_IP="192.168.10.10" 28 | DRUDE_SUBNET="192.168.10.1/24" 29 | DRUDE_DEFAULT_DNS="8.8.8.8" 30 | DRUDE_VBOX_DNS="10.0.2.3" 31 | 32 | #---------------------------- Global Variables -------------------------------- 33 | DOCKER_BETA="${DOCKER_BETA:-0}" 34 | 35 | if [[ $DOCKER_BETA -eq 0 ]]; then 36 | DEFAULT_DOCKER_HOST="tcp://$DRUDE_IP:2375" 37 | fi 38 | # boot2docker-vagrant does not support Docker TLS. 39 | # Make sure it is disabled for the current terminal session. 40 | unset DOCKER_TLS_VERIFY 41 | unset DOCKER_CERT_PATH 42 | 43 | DRUDE_BRANCH="${DRUDE_BRANCH:-master}" 44 | B2D_BRANCH="${B2D_BRANCH:-master}" 45 | 46 | # Allow image tag overrides for system services. See install_xyz_service() 47 | DRUDE_ITAG="${DRUDE_ITAG:-stable}" 48 | 49 | #---------------------------- Helper functions -------------------------------- 50 | 51 | DRUDE_YML_PATH='' #yml path value will be cached here 52 | DRUDE_PATH='' #drude path value will be cached here 53 | 54 | echo-red () { echo -e "${red}$1${NC}"; } 55 | echo-green () { echo -e "${green}$1${NC}"; } 56 | echo-green-bg () { echo -e "${green_bg}$1${NC}"; } 57 | echo-yellow () { echo -e "${yellow}$1${NC}"; } 58 | 59 | # Exits dsh if previous command exited with non-zero code 60 | if_failed () 61 | { 62 | if [ ! $? -eq 0 ]; then 63 | msg="error executing last command" 64 | if [[ "$1" != "" ]]; then msg="$1"; fi 65 | echo-red "dsh: $msg" 66 | exit 1 67 | fi 68 | } 69 | 70 | # Search for a file/directory in a directiry tree upwards. Return it's path. 71 | # @param $1 filename 72 | upfind () 73 | { 74 | if [[ $1 == '' ]]; then return 1; fi 75 | ( #incapsulate cd 76 | while [[ ! -f $1 ]] && [[ ! -d $1 ]] && [[ $PWD != / ]]; do 77 | cd ".." 78 | done; 79 | if [[ -f $1 ]] || [[ -d $1 ]]; then echo $PWD; fi 80 | ) 81 | } 82 | 83 | # Get path to docker-compose.yml using upfind 84 | get_yml_path () 85 | { 86 | if [ -z "$DRUDE_YML_PATH" ]; then 87 | DRUDE_YML_PATH=$(upfind "docker-compose.yml") 88 | fi 89 | echo "$DRUDE_YML_PATH" 90 | } 91 | 92 | # Get path to .drude folder using upfind 93 | get_drude_path () 94 | { 95 | if [ -z "$DRUDE_PATH" ]; then 96 | DRUDE_PATH=$(upfind ".drude") 97 | fi 98 | echo "$DRUDE_PATH" 99 | } 100 | 101 | # Returns absolute path 102 | # @param $1 file/dir relative path 103 | get_abs_path () 104 | { 105 | local _dir 106 | if [ -f $1 ]; then 107 | _dir=$(dirname $1) 108 | elif [ -d $1 ]; then 109 | _dir=$1 110 | else 111 | echo "Path \"$1\" does not exist" 112 | return 113 | fi 114 | local absolute=$( cd "${_dir}" ; pwd ) 115 | echo "$absolute" 116 | } 117 | 118 | # Return current path relative to project root with trailing slash 119 | get_current_relative_path () 120 | { 121 | # Check that we're inside project folder 122 | local proj_root=$(get_yml_path) 123 | local cwd=$(pwd) 124 | # if cwd substract proj_root is still cwd then it means we're out of proj_root (unsubstractable) 125 | # ex: cwd=/a/b/c/d, proj_root=/a/b/c, pathdiff==d 126 | # ex: cwd=/a/b, proj_root=/a/b/c, pathdiff==/a/b 127 | local pathdiff=${cwd#$proj_root/} 128 | echo $pathdiff 129 | } 130 | 131 | # Removes invisible residue from the string that remains leftover in Babun+docker-compose sometimes 132 | # @param $1 string to cleanup 133 | # @return clean string 134 | clean_string () 135 | { 136 | cleaned=$(echo "$1" | sed -e 's/[^a-zA-Z0-9_-]$//') 137 | echo ${cleaned} 138 | } 139 | 140 | # Get mysql connection string 141 | get_mysql_connect () 142 | { 143 | # Run drush forcing tty to false to avoid colored output string from drush. 144 | # Removes invisible residue from the connection string that remains 145 | #leftover in Babun+docker-compose sometimes. 146 | connection_string=$(echo $(DRUDE_IS_TTY=0 _run drush sql-connect) | sed -e 's/[^a-zA-Z0-9_-]$//') 147 | echo ${connection_string} 148 | } 149 | 150 | # Use this function for every docker-compose invocation. 151 | docker_compose () 152 | { 153 | # docker-compose cannot find docker-compose.yml in the path if there are symlinks on the way 154 | cwd=$(pwd) 155 | cd $(get_yml_path) 156 | 157 | docker-compose $* 158 | res=$? 159 | 160 | # switch back to the original path 161 | cd $cwd 162 | 163 | return $res 164 | } 165 | 166 | # Get container id by service name 167 | # @param $1 docker compose service name (e.g. cli) 168 | # @return docker container id 169 | get_container_id () 170 | { 171 | # Trim CR(\r) from the output, otherwise there will be issues passing it to the docker binary on Windows. 172 | echo $(docker_compose ps -q $1 | tr -d '\r') 173 | } 174 | 175 | #------------------------- Basics check functions ----------------------------- 176 | 177 | is_linux () 178 | { 179 | if [[ $IS_LINUX == "true" ]]; then return 0; fi 180 | 181 | local res=$(uname | grep 'Linux') 182 | if [[ ! "$res" == '' ]]; then 183 | IS_LINUX="true" 184 | return 0; 185 | else 186 | return 1; 187 | fi 188 | } 189 | 190 | is_windows () 191 | { 192 | local res=$(uname | grep 'CYGWIN_NT') 193 | if [[ "$res" != '' ]]; then 194 | return 0; 195 | else 196 | res=$(uname | grep 'MINGW32_NT') 197 | if [[ "$res" != '' ]]; then 198 | echo-red "dsh: Running from Git Bash is not supported" 199 | exit 1 200 | fi 201 | return 1; 202 | fi 203 | } 204 | 205 | # cheсks wether we are in boot2docker console 206 | is_boot2docker () 207 | { 208 | local res=$(uname -a|grep 'boot2docker') 209 | if [[ ! "$res" == '' ]]; then 210 | return 0; 211 | else 212 | return 1; 213 | fi 214 | } 215 | 216 | is_mac () 217 | { 218 | local res=$(uname | grep 'Darwin') 219 | if [[ ! "$res" == '' ]]; then 220 | return 0; 221 | else 222 | return 1; 223 | fi 224 | } 225 | 226 | is_docker_beta () 227 | { 228 | if [[ "$DOCKER_BETA" == "1" ]]; then 229 | return 0; 230 | else 231 | return 1; 232 | fi 233 | } 234 | 235 | # searches if binary exists and callable in PATH 236 | is_binary_found () 237 | { 238 | if [[ "$1" == "" ]]; then 239 | return 1; 240 | fi 241 | 242 | local bpath=$(which $1 2>/dev/null) 243 | 244 | if [[ "$bpath" != "" ]] && [ -f $(which $1) ]; then 245 | return 0 246 | else 247 | return 1 248 | fi 249 | } 250 | 251 | # checks if binary exists and fails is it isn't 252 | check_binary_found () 253 | { 254 | is_binary_found $1 255 | if_failed "$1 executable not found." 256 | } 257 | 258 | is_docker_running () 259 | { 260 | if is_linux || is_docker_beta; then 261 | local err 262 | local errcode 263 | # Check if docker is running via docker info. 264 | # This operation is instant even if docker is not running (assuming a socket is used). 265 | err=$(docker info >/dev/null 2>&1); errcode=$? 266 | # Print error details if available. We are looking for a specific case here: 267 | # e.g. "Error response from daemon: client is newer than server (client API version: 1.22, server API version: 1.21)" 268 | if [[ $err =~ 'Error' ]]; then echo $err; fi 269 | return $errcode 270 | else 271 | # On Mac and Windows - use netcat to check the host:port 272 | check_binary_found 'nc' 273 | if [[ $DOCKER_HOST == "" ]]; then 274 | return 1 275 | fi 276 | 277 | # Extract host and port from $DOCKER_HOST 278 | local host=$(echo $DOCKER_HOST | sed -e 's/\(tcp:\/\/\)*\([a-z0-9\.]*\):[0-9]*/\2/') 279 | local port=$(echo $DOCKER_HOST | sed -e 's/\(tcp:\/\/\)*[a-z0-9\.]*:\([0-9]*\)/\2/') 280 | 281 | if is_mac; then 282 | # nc on Mac needs -G for the connections timeout argument. 283 | nc -z -G 1 $host $port 2>/dev/null 1>/dev/null 284 | else 285 | nc -z -w 1 $host $port 2>/dev/null 1>/dev/null 286 | fi 287 | fi 288 | 289 | return $? 290 | } 291 | 292 | # Check whether shell is interactive 293 | # Otherwise we are running in a non-interactive script environment 294 | is_tty () 295 | { 296 | # Override option via $DRUDE_IS_TTY (true|false) env variable. 297 | if [[ $DRUDE_IS_TTY == 1 ]]; then 298 | return 0; 299 | fi 300 | if [[ $DRUDE_IS_TTY == 0 ]]; then 301 | return 1; 302 | fi 303 | 304 | [[ "$(/usr/bin/tty || true)" != "not a tty" ]] 305 | } 306 | 307 | #---------------------------- Other helper functions ------------------------------- 308 | 309 | testing_warn () 310 | { 311 | if ! is_tty; then return; fi 312 | if [[ ! $B2D_BRANCH == 'master' ]] || [[ ! $DRUDE_BRANCH == 'master' ]]; then 313 | echo-yellow "dsh: boot2docker - ${B2D_BRANCH}, drude - ${DRUDE_BRANCH}" 314 | fi 315 | } 316 | 317 | # Convert version string like 1.2.3 to integer for comparison 318 | # param $1 version string of 3 components max (e.g. 1.10.3) 319 | ver_to_int () 320 | { 321 | printf "%03d%03d%03d" $(echo "$1" | tr '.' ' ') 322 | } 323 | 324 | #---------------------------- Control functions ------------------------------- 325 | 326 | check_dsh_environment () 327 | { 328 | check_docker_running 329 | check_yml 330 | } 331 | 332 | check_docker_running () 333 | { 334 | check_binary_found 'docker' 335 | check_binary_found 'docker-compose' 336 | if ! is_docker_running; then 337 | local msg="dsh: Unable to connect to the Docker daemon" 338 | if [ ! -z "$DOCKER_HOST" ]; then 339 | msg="$msg via '$DOCKER_HOST'" 340 | fi 341 | echo-red "$msg" 342 | 343 | if is_docker_beta; then 344 | echo-red "Make sure the Docker Beta app is running" 345 | elif is_mac || is_windows; then 346 | echo-red "Drude VM may not be running. It can be started with 'dsh up'" 347 | _confirm "Run 'dsh up' now?" 348 | up 349 | if_failed "Could not start the VM properly" 350 | fi 351 | 352 | exit 1 353 | fi 354 | } 355 | 356 | # Check that docker-compose.yml (and Vagrantfile on Win/Mac) present. Fail otherwise 357 | check_yml() 358 | { 359 | yml_path=$(get_yml_path) 360 | if [[ "$yml_path" == "" ]] ; then 361 | echo-red "dsh: docker-compose.yml was not found in your directory tree" 362 | exit 1 363 | fi 364 | 365 | if is_linux || is_docker_beta; then 366 | return; # linux does not need vagrant 367 | fi 368 | 369 | vagrant_path=$(upfind "Vagrantfile") 370 | if [[ "$vagrant_path" == "" ]] ; then 371 | echo-red "dsh: Vagrantfile was not found in your directory tree" 372 | exit 1 373 | fi 374 | } 375 | 376 | # Check that command is run inside project folder 377 | check_drush_path () 378 | { 379 | local pathdiff=$(get_current_relative_path) 380 | if [[ "$(pwd)" == "$pathdiff" ]]; then 381 | echo-red "dsh: This command must be run inside Drupal's document root" 382 | exit 1 383 | fi 384 | } 385 | 386 | # Yes/no confirmation dialog with an optional message 387 | # @param $1 confirmation message 388 | _confirm () 389 | { 390 | # Skip checks if not running interactively (not a tty or not on Windows) 391 | if ! is_tty; then return 0; fi 392 | 393 | while true; do 394 | read -p "$1 [y/n]: " answer 395 | case $answer in 396 | [Yy]|[Yy][Ee][Ss] ) 397 | break 398 | ;; 399 | [Nn]|[Nn][Oo] ) 400 | exit 1 401 | ;; 402 | * ) 403 | echo 'Please answer yes or no.' 404 | esac 405 | done 406 | } 407 | 408 | # Display desktop notification (Mac only) 409 | # @param $1 title 410 | # @param $2 message 411 | _notify () 412 | { 413 | if is_mac && [[ "$1" != "" ]]; then 414 | osascript -e 'display notification "'"$2"'" with title "'"$1"'"' 415 | fi 416 | } 417 | 418 | # Make sure $DOCKER_HOST is not empty 419 | check_docker_host () 420 | { 421 | if is_linux ; then return 0; fi 422 | # don't change DOCKER_HOST if it's nonempty 423 | if [[ "$DOCKER_HOST" != "" ]]; then 424 | return 0; 425 | else 426 | # set Drude's default DOCKER_HOST var 427 | DOCKER_HOST=$DEFAULT_DOCKER_HOST 428 | export DOCKER_HOST=$DEFAULT_DOCKER_HOST 429 | fi 430 | } 431 | check_docker_host #perform this check in any case 432 | 433 | #-------------------------- Containers management ----------------------------- 434 | 435 | _start_containers () 436 | { 437 | ssh_add 438 | echo-green "Starting services..." 439 | docker_compose up -d && \ 440 | _vhost_proxy_connect && \ 441 | _set_cli_uid 442 | } 443 | 444 | # @param $1 container_name 445 | _restart_containers () 446 | { 447 | echo-green "Restarting services..." 448 | docker_compose restart $* && \ 449 | _vhost_proxy_connect && \ 450 | _set_cli_uid 451 | } 452 | 453 | # @param $1 "-a" || "--all" 454 | _stop_containers () 455 | { 456 | echo-yellow "Stopping services..." 457 | if [[ $1 == '-a' ]] || [[ $1 == '--all' ]]; then 458 | # stop all but system containers (--label "group=system") 459 | docker ps --format '{{.ID}} {{.Label "group"}}' | grep -v 'system' | xargs docker stop 460 | fi 461 | if [[ "$1" == "proxy" ]] ; then 462 | echo-green 'Stopping Drude HTTP/HTTPS reverse proxy service...' 463 | docker stop vhost-proxy 464 | return 465 | fi 466 | 467 | if [[ "$1" == "dns" ]] ; then 468 | echo-green 'Stopping Drude DNS service...' 469 | docker stop dns 470 | return 471 | fi 472 | 473 | if [[ "$1" == "ssh-agent" ]] ; then 474 | echo-green 'Stopping Drude ssh-agent service...' 475 | docker stop ssh-agent 476 | return 477 | fi 478 | docker_compose stop 479 | } 480 | 481 | # @param $1 container_name 482 | _remove_containers () 483 | { 484 | if [[ $1 == "" ]]; then 485 | echo-yellow "Removing containers..." 486 | fi 487 | docker_compose kill $* && docker_compose rm -vaf $* 488 | } 489 | 490 | _docker_cleanup () 491 | { 492 | if [[ "$1" == "--hard" ]] && [[ "$(docker ps -aqf status=exited)" != "" ]]; then 493 | echo -e "${red}WARNING: ${yellow}Preparing to delete all currently stopped containers:${NC}" 494 | docker ps -af status=exited --format "{{.Label \"com.docker.compose.project\"}}_{{.Label \"com.docker.compose.service\"}}\t\t{{.Status}} ({{.Image}})" 495 | printf '–%.0s' $(seq 1 40) 496 | echo -e "${yellow}" 497 | _confirm "Continue?" 498 | echo -e "${NC}" 499 | #-- 500 | echo-green "Removing stopped containers..." 501 | docker ps -aqf status=exited | xargs docker rm -vf 502 | fi 503 | 504 | echo-green "Cleaning up images..." 505 | docker images -qf dangling=true | xargs docker rmi 2>1 506 | } 507 | 508 | # Connect vhost-proxy to all bridge networks on the host 509 | _vhost_proxy_connect () 510 | { 511 | echo-green "Connecting vhost-proxy to networks..." 512 | docker network ls -q --filter name=_default | while read network; do 513 | docker network connect $network vhost-proxy >/dev/null 2>&1 || true 514 | done 515 | } 516 | 517 | #------------------------------ Help functions -------------------------------- 518 | 519 | # Show help for dsh or for certain command 520 | # $1 name of command to show help for 521 | show_help () 522 | { 523 | local commands_path="$(get_drude_path)/$DRUDE_COMMANDS_PATH" 524 | local custom_commands_list 525 | 526 | echo "Drude Shell $DSH_VERSION help." 527 | 528 | # Show help for certain command 529 | if [[ ! -z "$1" ]]; then 530 | # Check for help function for specific command 531 | type "show_help_$1" 1>/dev/null 2>/dev/null 532 | if [ $? -eq 0 ]; then 533 | show_help_$1 534 | exit 535 | fi 536 | # Check for custom command file 537 | if [ -f "$commands_path/$1" ]; then 538 | echo -en "${green}dsh $1${NC} - " 539 | cat "$commands_path/$1" | grep '^##' | sed "s/^##[ ]*//g" 540 | echo 541 | exit 542 | fi 543 | fi 544 | 545 | echo 546 | if is_linux; then 547 | echo " start (up) Start project services (containers)" 548 | else 549 | echo " start (up) Start vagrant vm (if stopped) and project services (containers)" 550 | fi 551 | echo " stop (down) Stop project services (containers)" 552 | echo " -a (--all) Stop all running containers from all Docker projects (except where group=system)" 553 | echo " restart [service] Restart all current project services (containers) or specified service" 554 | if ! is_linux; then 555 | echo " reload Restart vagrant vm" 556 | echo " halt Stop vagrant vm" 557 | fi 558 | echo " status (st, ps) Show project services (containers) status" 559 | echo " -a (--all) Show status of all running containers from all Docker projects" 560 | echo " reset [service] Recreate service(s). If no parameter given recreates all project services." 561 | echo " See 'dsh help reset' for more details on resetting Drude system services." 562 | echo " remove [service] Remove project services (containers). If no parameter given removes all project services" 563 | echo 564 | echo " bash [service] Open bash to service (container). If no service specified defaults to 'cli'" 565 | echo " exec (run) Execute a command in 'cli' container (Usage: dsh exec [params])" 566 | echo " logs [service] Show docker logs for service (container)" 567 | echo 568 | echo " exec-url Download script from URL and run it. URL should be public." 569 | echo 570 | echo " drush [command] Execute Drush command (usage: dsh drush [command] [option] [option]...)" 571 | echo " cc [cache_type] Clear Drupal 7 caches (\"dsh cc\" is equal to \"dsh cc all\")" 572 | echo " drupal [command] Execute Drupal Console command (Drupal 8)" 573 | echo 574 | echo " mysql (sqlc) Opens mysql shell to current project database" 575 | echo " mysql-import Truncate database and import from sql dump (usage: dsh mysql-import )" 576 | echo " (sqli) Note: DB dump file should be inside your project folder" 577 | echo 578 | echo " behat [--path=path] Run Behat tests from path (relative to project root). Default: tests/behat" 579 | echo 580 | echo " ssh-add [-lD] [key] Adds private key identities to the authentication agent. See 'dsh help ssh-add'" 581 | echo 582 | if is_linux; then 583 | echo " install Install/check prerequisites and drude config" 584 | else 585 | echo " install Install/check prerequisites, boot2docker and drude config" 586 | fi 587 | echo " install prerequisites Only install prerequisites" 588 | if ! is_linux; then 589 | echo " install boot2docker Only install boot2docker" 590 | fi 591 | echo " install drude-config Only install the latest default docker-compose.yml" 592 | echo " install autocomplete Install commands autocomplete for Bash" 593 | echo 594 | echo " update prerequisites Update prerequisites" 595 | if ! is_linux; then 596 | echo " update boot2docker Update boot2docker-vagrant box" 597 | fi 598 | echo " update images Update container images" 599 | echo " update dsh Update dsh itself (ex. dsh self-update)" 600 | echo 601 | echo " cleanup Cleanup images to save space (--hard to clean up containers)" 602 | echo " system-information (sysinfo) Show diagnostics information for bug reporting" 603 | if ! is_linux; then 604 | echo " vmstat Show vagrant vm usage statistics" 605 | fi 606 | echo " version (v, -v) Print dsh version. [v, -v] - prints short version" 607 | 608 | # Show list of custom commands and their help if available 609 | if [ ! -z "$(get_drude_path)" ]; then 610 | custom_commands_list=$(ls "$commands_path" 2>/dev/null | tr "\n" " ") 611 | if [ ! -z "$custom_commands_list" ]; then 612 | echo 613 | echo -e "Custom commands found in ${yellow}$DRUDE_COMMANDS_PATH${NC}:"; 614 | for cmd_name in $custom_commands_list 615 | do 616 | # command description is lines that start with ## 617 | local cmd_desc=$(cat "$commands_path/$cmd_name" | grep '^##' | sed "s/^##[ ]*//g" | head -1 --) 618 | printf "\t%-23s" $cmd_name 619 | echo " $cmd_desc" 620 | done 621 | fi 622 | fi 623 | 624 | echo 625 | } 626 | 627 | show_help_ssh-add () 628 | { 629 | echo-green "dsh ssh-add - Add private key identities to the ssh-agent." 630 | echo "Usage: dsh ssh-add [-lD] [key]" 631 | echo 632 | echo "When run without arguments, picks up the default key file (~/.ssh/id_rsa or ~/.ssh/id_dsa)." 633 | echo "A custom key name can be given as an argument: dsh ssh-add ." 634 | echo 635 | echo -e "${yellow}NOTE${NC}: is the file name (not full path) within ${yellow}~/.ssh${NC}." 636 | echo "Example: dsh ssh-add my_custom_key_rsa" 637 | echo 638 | echo "The options are as follows:" 639 | echo " -D Deletes all identities from the agent." 640 | echo " -l Lists fingerprints of all identities currently represented by the agent." 641 | echo 642 | } 643 | 644 | show_help_reset () 645 | { 646 | echo-green "dsh reset - Recreate services/containers. Equal to dsh stop, dsh remove, dsh start" 647 | echo 648 | echo-green "Parameters: one or more service names. Examples:" 649 | echo " dsh reset web Restart 'web' service" 650 | echo " dsh reset web cli Restart 'web' and 'cli' services" 651 | echo " dsh reset Restart all project services" 652 | echo 653 | echo-green "System services" 654 | echo -e "Drude has 3 system services." 655 | echo -e "Names ${yellow}'dns'${NC}, ${yellow}'proxy'${NC}, ${yellow}'ssh-agent'${NC} and ${yellow}'system'${NC} are reserved and are not recommended for use." 656 | echo " dsh reset dns Recreate Drude DNS service" 657 | echo -e " dsh reset proxy Recreate Drude HTTP/HTTPS reverse proxy service (resolves ${yellow}*.drude${NC} domain names into container IPs)" 658 | echo " dsh reset ssh-agent Recreate Drude ssh-agent service" 659 | echo " dsh reset system Recreate all Drude system services" 660 | echo 661 | } 662 | 663 | # Display dsh version 664 | # @option --short - Display only the version number 665 | version () 666 | { 667 | if [[ $1 == '--short' ]]; then 668 | echo "$DSH_VERSION" 669 | else 670 | testing_warn 671 | echo "dsh version: $DSH_VERSION" 672 | fi 673 | } 674 | 675 | # return bash completion words 676 | # @param $1 command to return words for 677 | bash_comp_words () 678 | { 679 | case $1 in 680 | install) 681 | echo "prerequisites boot2docker drude-config" 682 | exit 0 683 | ;; 684 | update) 685 | echo "prerequisites boot2docker images dsh" 686 | exit 0 687 | ;; 688 | dsh) 689 | echo "start up stop down halt reload restart status vmstat reset remove bash exec logs run mysql sqlc mysql-import sqli exec-url drush drupal behat install update self-update version help" 690 | exit 0 691 | ;; 692 | *) 693 | exit 1 #return 1 to completion function to prevent completion is we don't know what to do 694 | esac 695 | } 696 | 697 | #------------------------------- User Commands ----------------------------------- 698 | # Start containers 699 | up () 700 | { 701 | check_yml 702 | if is_linux || is_boot2docker || is_docker_beta; then 703 | _start_containers 704 | else 705 | check_binary_found 'vagrant' 706 | local started 707 | if ! is_docker_running; then 708 | echo-green "dsh: Starting vagrant vm..." 709 | vagrant up 710 | started=$? 711 | else 712 | started=0 713 | fi 714 | if [ $started -eq 0 ] ; then 715 | _start_containers 716 | fi 717 | fi 718 | } 719 | 720 | # Stop containers 721 | down () 722 | { 723 | check_dsh_environment 724 | _stop_containers "$@" 725 | } 726 | 727 | # Stop Vagrant box 728 | halt () 729 | { 730 | check_dsh_environment 731 | if is_linux || is_boot2docker; then 732 | _stop_containers 733 | else 734 | vagrant halt 735 | fi 736 | } 737 | 738 | # Restart container(s) 739 | # @param $1 container_name 740 | restart () 741 | { 742 | check_dsh_environment 743 | _restart_containers $* 744 | } 745 | 746 | # Restart Vagrant and start containers again 747 | reload () 748 | { 749 | check_yml 750 | if is_linux || is_boot2docker || is_docker_beta; then 751 | _start_containers 752 | else 753 | check_binary_found 'vagrant' 754 | echo-green "dsh: Restarting vagrant vm..." 755 | vagrant reload 756 | if [ $? -eq 0 ]; then 757 | _start_containers 758 | fi 759 | fi 760 | } 761 | 762 | # output status of Drude if stopped or containers if started 763 | # @param $1 Show containers from all projects (-a) 764 | status () 765 | { 766 | check_dsh_environment 767 | 768 | if [[ "$1" == "-a" ]] || [[ "$1" == "--all" ]]; then 769 | docker ps 770 | else 771 | docker_compose ps 772 | fi 773 | } 774 | 775 | vmstat () 776 | { 777 | local vagrant_path=$(upfind Vagrantfile) 778 | if [[ $vagrant_path == "" ]]; then 779 | echo-red "dsh: Vagrantfile was not found in your directory tree" 780 | exit 1 781 | fi 782 | check_binary_found vboxmanage 783 | local machine_id="${vagrant_path}/.vagrant/machines/boot2docker/virtualbox/id" 784 | if [ ! -f $machine_id ]; then 785 | echo-red "Could not find id file $machine_id" 786 | exit 1 787 | fi 788 | local id=$(cat $machine_id) 789 | metrics="CPU/Load/User,CPU/Load/Kernel,Disk/Usage/Used,RAM/Usage/Used,Net/Rate/Rx,Net/Rate/Tx" 790 | vboxmanage metrics setup --period 1 --samples 1 "$id" 791 | sleep 1 792 | vboxmanage metrics query "$id" $metrics 793 | } 794 | 795 | # Add key to ssh-agent or run ssh-add with provided @param 796 | # @param $1 -D, -l or path to custom key 797 | ssh_add () { 798 | # Check if ssh-agent container is running 799 | local running=$(docker inspect --format="{{ .State.Running }}" ssh-agent 2>/dev/null) 800 | [[ "$running" != "true" ]] && return 801 | 802 | local ssh_path="$HOME/.ssh" 803 | local key_path="" 804 | # Home folder mount in boot2docker 805 | if ! is_linux; then 806 | ssh_path="/.home/.ssh" 807 | fi 808 | 809 | # When no arguments provided, check if ssh-agent already has at least one identity. If so, stop here. 810 | docker exec ssh-agent ssh-add -l >/dev/null 811 | if [[ $1 == "" && $? == 0 ]]; then return; fi 812 | 813 | ssh_arg="$@" 814 | if [[ $1 != "-l" && $1 != "-D" && $ssh_arg != "" ]]; then ssh_arg="/.ssh/$@"; fi 815 | 816 | # When $key_path is empty, ssh-agent will be looking for both id_rsa and id_dsa in the home directory. 817 | $winpty_cmd docker run --rm -it --volumes-from=ssh-agent -v "$ssh_path:/.ssh" "blinkreaction/ssh-agent:${DRUDE_ITAG}" ssh-add "$ssh_arg" 818 | return $? 819 | } 820 | 821 | #----- Installations and updates ----- 822 | 823 | # Install required software on Mac or Win. Check installed software on Linux 824 | install_prerequisites () 825 | { 826 | testing_warn 827 | if is_docker_running; then 828 | if is_linux; then 829 | stopcmd="'dsh stop'" 830 | else 831 | stopcmd="'dsh halt'" 832 | fi 833 | echo-yellow "WARNING: Docker is running. It's recommended to stop Docker first with ${stopcmd} " 834 | _confirm "Stop Docker now?" 835 | 836 | if is_linux || is_boot2docker; then 837 | _stop_containers 838 | else 839 | vagrant halt 840 | fi 841 | fi 842 | 843 | echo-green "Installing prerequisites..." 844 | 845 | if is_windows ; then 846 | # installing prerequisites 847 | local presetup_script 848 | presetup_script=$(curl -fsS https://raw.githubusercontent.com/blinkreaction/boot2docker-vagrant/$B2D_BRANCH/scripts/presetup-win.sh) 849 | if_failed "Could not get 'presetup-win.sh'. Please check your internet connection" 850 | bash <(echo "$presetup_script") 851 | read -p "Press enter after the installation in another console window is done..." 852 | elif is_linux ; then 853 | install_ubuntu 854 | else # mac 855 | local presetup_script 856 | presetup_script=$(curl -fsS https://raw.githubusercontent.com/blinkreaction/boot2docker-vagrant/$B2D_BRANCH/scripts/presetup-mac.sh) 857 | if_failed "Could not get 'presetup-mac.sh'. Please check your internet connection" 858 | bash <(echo "$presetup_script") 859 | fi 860 | } 861 | 862 | install_proxy_service () 863 | { 864 | docker rm -f vhost-proxy >/dev/null 2>&1 || true 865 | docker run -d --name vhost-proxy --label "group=system" --restart=always --privileged --userns=host \ 866 | -p 80:80 -p 443:443 \ 867 | -v /var/run/docker.sock:/var/run/docker.sock \ 868 | "blinkreaction/nginx-proxy:${DRUDE_ITAG}" >/dev/null 2>&1 869 | } 870 | 871 | install_dns_service () 872 | { 873 | # Use default DNS on Linux and VirtualBox's buit-in DNS if using boot2docker 874 | local dns 875 | if is_linux; then dns=$DRUDE_DEFAULT_DNS; else dns=$DRUDE_VBOX_DNS; fi 876 | 877 | # Support for boot2docker-vagrant 878 | local docker_ip_map="-p 172.17.42.1:53:53/udp" 879 | if is_linux; then docker_ip_map=""; fi 880 | 881 | docker rm -f dns >/dev/null 2>&1 || true 882 | docker run -d --name dns --label "group=system" --restart=always --privileged --userns=host \ 883 | -p $DRUDE_IP:53:53/udp $docker_ip_map --cap-add=NET_ADMIN --dns $dns \ 884 | -v /var/run/docker.sock:/var/run/docker.sock \ 885 | "blinkreaction/dns-discovery:${DRUDE_ITAG}" >/dev/null 2>&1 886 | } 887 | 888 | install_sshagent_service () 889 | { 890 | docker rm -f ssh-agent >/dev/null 2>&1 || true 891 | docker run -d --name ssh-agent --label "group=system" --restart=always --privileged --userns=host \ 892 | -v /var/run/docker.sock:/var/run/docker.sock \ 893 | "blinkreaction/ssh-agent:${DRUDE_ITAG}" >/dev/null 2>&1 894 | } 895 | 896 | # Install Docker and setup Drude on Ubuntu 14.04+ 897 | install_ubuntu () 898 | { 899 | if [ -r /etc/lsb-release ]; then 900 | lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")" 901 | lsb_release="$(. /etc/lsb-release && echo "$DISTRIB_RELEASE")" 902 | fi 903 | 904 | if [[ $lsb_dist != 'Ubuntu' || $(ver_to_int $lsb_release) < $(ver_to_int '14.04') ]]; then 905 | echo-red "dsh: prerequisites installation is currently supported only on Ubuntu 14.04+" 906 | if is_tty; then 907 | echo-yellow "You can continue at your own risk, if you know your Linux distribution is compatible with Ubuntu 14.04+" 908 | _confirm "Are you sure you want to continue?" 909 | else 910 | exit 1 911 | fi 912 | fi 913 | 914 | echo-green "Installing Docker..." 915 | # Stop docker dervice if it exists 916 | if sudo service docker status 2>/dev/null; then 917 | echo "Stopping docker service..." 918 | sudo service docker stop 2>/dev/null 919 | fi 920 | curl -sSL https://get.docker.com/ | sh && \ 921 | sudo usermod -aG docker $(whoami) 922 | sudo service docker start 2>/dev/null 923 | sudo docker version 924 | if_failed "Docker installation/upgrade has failed." 925 | 926 | echo-green "Installing Docker Compose..." 927 | sudo curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && \ 928 | sudo chmod +x /usr/local/bin/docker-compose && \ 929 | docker-compose --version 930 | if_failed "Docker Compose installation/upgrade has failed." 931 | 932 | echo-green "Adding a subnet for Drude..." 933 | # Make sure we don't do this twice 934 | if ! grep -q $DRUDE_SUBNET /etc/network/interfaces; then 935 | cat > /tmp/drude.ip.addr </dev/null /etc/resolver/drude 994 | fi 995 | } 996 | 997 | # Download latest Drude config file 998 | install_drude_config () 999 | { 1000 | testing_warn 1001 | local docker_compose_yml 1002 | docker_compose_yml=$(curl -kfsS "https://raw.githubusercontent.com/blinkreaction/drude/$DRUDE_BRANCH/docker-compose.yml") 1003 | if_failed "Could not get latest docker-compose.yml version." 1004 | 1005 | echo "$docker_compose_yml" | tee "docker-compose.yml" >/dev/null 1006 | if_failed "Could not write to docker-compose.yml" 1007 | echo-green "Latest version of docker-compose.yml was downloaded." 1008 | } 1009 | 1010 | # Install shell commands autocomplete script 1011 | install_autocomplete () 1012 | { 1013 | local autocomplete_script 1014 | autocomplete_script=$(curl -kfsS "https://raw.githubusercontent.com/blinkreaction/drude/$DRUDE_BRANCH/bin/dsh-bash-complete") 1015 | if_failed "Autocomplete script download has failed" 1016 | 1017 | destination="/usr/local/bin/dsh-bash-autocomplete" 1018 | echo "$autocomplete_script" | tee "$destination" >/dev/null 1019 | if_failed "Failed to write file to $destination" 1020 | echo-green "Script saved to $destination" 1021 | chmod +x $destination 1022 | 1023 | SOURCE_FILE=".bash_profile" 1024 | grep -q "$destination" $HOME/$SOURCE_FILE 1025 | if [[ $? -ne 0 ]]; then 1026 | echo -e ". $destination" >> $HOME/$SOURCE_FILE 1027 | if_failed "Failed to write file to $HOME/$SOURCE_FILE" 1028 | echo-green "Autocomplete appended to $HOME/$SOURCE_FILE" 1029 | echo-yellow "dsh: Please restart your bash session to apply" 1030 | fi 1031 | } 1032 | 1033 | # Install everything: prerequisites, boot2docker and drude config 1034 | install () 1035 | { 1036 | if [[ "$1" == "prerequisites" ]]; then 1037 | install_prerequisites 1038 | elif [[ "$1" == "boot2docker" ]]; then 1039 | echo -e "${green}ATTENTION:${NC} Vagrantfile and vagrant.yml will be downloaded to ${green}$(pwd)${NC}" 1040 | echo -e " If that is not correct please cancel, cd to proper dir and re-run command." 1041 | _confirm "Continue with download to $(pwd)?" 1042 | install_boot2docker 1043 | elif [[ "$1" == "drude-config" ]]; then 1044 | install_drude_config 1045 | elif [[ "$1" == "autocomplete" ]]; then 1046 | install_autocomplete 1047 | else # Full setup 1048 | local cwd=$(pwd) 1049 | install_prerequisites 1050 | if ! is_linux ; then 1051 | cd .. 1052 | _confirm "Install Vagrantfile to $(pwd) (This should be your folder)?" 1053 | install_boot2docker 1054 | cd $cwd 1055 | fi 1056 | _confirm "Install default docker-compose.yml to $(pwd) (This should be your folder)?" 1057 | install_drude_config 1058 | echo-green "Please restart you terminal shell to pick up DOCKER_HOST environment variable and then use 'dsh up' to start Drude" 1059 | fi 1060 | } 1061 | 1062 | # Update container images 1063 | update_images () 1064 | { 1065 | check_dsh_environment 1066 | docker pull "blinkreaction/nginx-proxy:${DRUDE_ITAG}" 1067 | docker pull "blinkreaction/dns-discovery:${DRUDE_ITAG}" 1068 | docker pull "blinkreaction/ssh-agent:${DRUDE_ITAG}" 1069 | docker_compose pull 1070 | echo-green "Resetting system services..." 1071 | reset system 1072 | up 1073 | } 1074 | 1075 | # Update Vagrant Box 1076 | update_boot2docker () 1077 | { 1078 | testing_warn 1079 | if ! is_tty; then 1080 | echo-red "dsh: update is not allowed in a non-interactive environment." 1081 | return 1 1082 | fi 1083 | 1084 | if ! is_windows && ! is_mac ; then 1085 | echo-red "dsh: drude boot2docker box update should be used on Mac and Win only" 1086 | return 1 1087 | fi 1088 | 1089 | # don't download update if we can't locate Vagrantfile 1090 | vagrant_path=$(upfind "Vagrantfile") 1091 | if [[ "$vagrant_path" == "" ]] ; then 1092 | echo-red "dsh: Vagrantfile not found in your directory tree" 1093 | return 1 1094 | fi 1095 | 1096 | local cwd=$(pwd) 1097 | echo-green "Installing boot2docker update..." 1098 | 1099 | # get current version 1100 | local b2d_version=$(cat $DRUDE_B2D_VERSION 2>/dev/null) 1101 | if [[ "$b2d_version" = "" ]]; then b2d_version="undetected version"; fi 1102 | 1103 | # get new version 1104 | local b2d_new_version 1105 | b2d_new_version=$(curl -kfsS https://raw.githubusercontent.com/blinkreaction/boot2docker-vagrant/$B2D_BRANCH/VERSION) 1106 | if_failed "Could not get latest boot2docker version. Please check your internet connection" 1107 | 1108 | # update boot2docker 1109 | local forced_update=''; 1110 | local destroy_box=1; 1111 | if [[ "$1" == "-f" ]] || [[ "$2" == "-f" ]]; then forced_update="(forced update)"; fi 1112 | if [[ "$1" == "-n" ]] || [[ "$2" == "-n" ]]; then destroy_box=0; fi 1113 | 1114 | if [[ ! "$b2d_new_version" == "$b2d_version" ]] || [ -n "$forced_update" ]; then 1115 | echo -e "boot2docker update available: ${green}$b2d_new_version $forced_update${NC} (you have $b2d_version)." 1116 | if [ $destroy_box -eq 1 ]; then 1117 | echo -e "${red}Update will destroy and re-create your Vagrant box${NC} (run with -n if you know re-creation can be skipped this time)" 1118 | _confirm "Please confirm." 1119 | else 1120 | echo-green "Vagrant box will not be re-created" 1121 | fi 1122 | 1123 | cd $vagrant_path 1124 | echo "Vagrantfile is found in "$(pwd) 1125 | 1126 | echo-green "dsh: Downloading boot2docker install script..." 1127 | local b2d_setup_script 1128 | b2d_setup_script=$(curl -kfsS https://raw.githubusercontent.com/blinkreaction/boot2docker-vagrant/$B2D_BRANCH/scripts/setup.sh) 1129 | if_failed "Could not get latest boot2docker version. Please check your internet connection" 1130 | 1131 | echo "dsh: Creating backups in $DRUDE_CONFIG_BACKUP_DIR..." 1132 | local timestamp=$(date +%s) 1133 | cp -v Vagrantfile $DRUDE_CONFIG_BACKUP_DIR/Vagrantfile.$timestamp && \ 1134 | cp -v vagrant.yml $DRUDE_CONFIG_BACKUP_DIR/vagrant.yml.$timestamp 1135 | if_failed "Unable to perform configuration backups. Aborting..." 1136 | # contingency. remove old backups 1137 | rm "$DRUDE_CONFIG_DIR/Vagrantfile.*" 2>/dev/null 1138 | rm "$DRUDE_CONFIG_DIR/vagrant.yml.*" 2>/dev/null 1139 | 1140 | if [ $destroy_box -eq 1 ]; then 1141 | echo-yellow "dsh: Destroying vagrant box..." 1142 | vagrant destroy -f 1143 | fi 1144 | 1145 | echo-green "dsh: Running boot2docker install script..." 1146 | # calling bash interactively 1147 | bash <(echo "$b2d_setup_script") 1148 | 1149 | if_failed "boot2docker install script error" 1150 | 1151 | # update recorded boot2docker version 1152 | echo $b2d_new_version > $DRUDE_B2D_VERSION 1153 | echo -e "boot2docker ${green}$b2d_new_version${NC} was installed" 1154 | else 1155 | echo "boot2docker $b2d_version you have is the latest version (-f to force update)" 1156 | fi 1157 | 1158 | cd $cwd # go back where we were 1159 | } 1160 | 1161 | # Update dsh itself 1162 | update_dsh () 1163 | { 1164 | testing_warn 1165 | echo "Downloading..." 1166 | local new_dsh 1167 | new_dsh=$(curl -kfsS "https://raw.githubusercontent.com/blinkreaction/drude/$DRUDE_BRANCH/bin/dsh") 1168 | if_failed "Download has failed." 1169 | 1170 | # Check if update is a major version. Show warning is needed 1171 | local new_version=$(echo "$new_dsh" | grep "^DSH_VERSION=" | cut -f 2 -d "=") 1172 | local current_major_version=$(echo $DSH_VERSION | cut -d "." -f 1) 1173 | local new_major_version=$(echo $new_version | cut -d "." -f 1) 1174 | if [[ "$current_major_version" != "$new_major_version" ]]; then 1175 | echo -e "${red_bg} WARNING ${NC} ${red}Non-backwards compatible version update${NC}" 1176 | echo -e "Updating from ${yellow}$DSH_VERSION${NC} to ${yellow}$new_version${NC} is a non-backwards compatible update." 1177 | echo "You might be not able to use you current Drude environment if you proceed." 1178 | echo -e "Please read update documentation: ${yellow}https://github.com/blinkreaction/drude#updates${NC}" 1179 | _confirm "Continue with update?" 1180 | fi 1181 | 1182 | # saving to file 1183 | echo "$new_dsh" | sudo tee /usr/local/bin/dsh > /dev/null 1184 | if_failed "Could not write /usr/local/bin/dsh." 1185 | sudo chmod +x /usr/local/bin/dsh 1186 | 1187 | local new_version=$(head /usr/local/bin/dsh | grep "^DSH_VERSION=" | cut -f 2 -d "=") 1188 | echo-green "dsh updated to ${new_version}" 1189 | exit 1190 | } 1191 | 1192 | check_for_updates () 1193 | { 1194 | # Never trigger in scripts 1195 | if ! is_tty; then return; fi 1196 | 1197 | local timestamp; local last_check; local next_check 1198 | timestamp=$(date +%s) 1199 | last_check=$(cat $DRUDE_LAST_CHECK 2>/dev/null) 1200 | # Set last_check to 0 if empty 1201 | last_check="${last_check:-0}" 1202 | # Check once a week 1203 | next_check=$(($last_check+604800)) 1204 | if [ $timestamp -le $next_check ]; then 1205 | return; 1206 | fi 1207 | 1208 | echo 'dsh: checking for updates...' 1209 | local new_dsh; local new_version 1210 | # Always write current timestamp to last check file 1211 | echo $timestamp > $DRUDE_LAST_CHECK 1212 | # No -S for curl here to be completely silent. Connection timeout 1 sec, total max time 3 sec or fail 1213 | new_dsh=$(curl -kfs --connect-timeout 1 --max-time 3 https://raw.githubusercontent.com/blinkreaction/drude/$DRUDE_BRANCH/bin/dsh) 1214 | new_version=$(echo "$new_dsh" | grep "^DSH_VERSION=" | cut -f 2 -d "=") 1215 | if [ $(ver_to_int $new_version) -gt $(ver_to_int $DSH_VERSION) ]; then 1216 | echo-green-bg " UPDATE AVAILABLE " 1217 | echo -e "${green}dsh${NC} [ $DSH_VERSION --> $new_version ] (run ${green}dsh update dsh${NC} to update)" 1218 | echo "Press enter to continue with your command." 1219 | read -p '' 1220 | fi 1221 | } 1222 | 1223 | #-------------------------- Execution commands ----------------------------- 1224 | 1225 | # Start an interactive bash session in a container 1226 | # @param $1 container name 1227 | _bash () 1228 | { 1229 | # Interactive shell requires a tty. 1230 | # On Windows we assume we run interactively via winpty. 1231 | if ! is_tty; then 1232 | echo "Interactive bash console in a non-interactive enveronment!? Nope, won't happen." 1233 | return 1 1234 | fi 1235 | 1236 | # Pass container name to _run 1237 | CONTAINER_NAME=$1 _run bash -i 1238 | } 1239 | 1240 | # Run a command in the cli container changing dir to the same folder 1241 | # @param $* command with it's params to run 1242 | _run () 1243 | { 1244 | check_dsh_environment 1245 | 1246 | if [[ "$CONTAINER_NAME" == "" ]]; then CONTAINER_NAME='cli'; fi 1247 | container_id=$(get_container_id $CONTAINER_NAME) 1248 | 1249 | # 1) $winpty_cmd 1250 | local winpty_cmd 1251 | # Running docker exec interactively on Windows requires workarounds 1252 | if is_windows; then 1253 | # Workaround - run docker exec via winpty to get a tty console in cygwin. 1254 | if is_binary_found 'winpty'; then 1255 | winpty_cmd='winpty' 1256 | else 1257 | echo-red 'Winpty binary is missing.' 1258 | echo 'Run "dsh install prerequisites" to install it.' 1259 | exit 1 1260 | fi 1261 | fi 1262 | 1263 | # 2) cmd 1264 | local cmd 1265 | 1266 | local cdir 1267 | # Only chdir to the same dir in cli container 1268 | # RUN_NO_CDIR can be used to override this (used in mysql_import) 1269 | if [[ $CONTAINER_NAME == "cli" ]] && [[ $RUN_NO_CDIR != 1 ]]; then 1270 | local path 1271 | path=$(get_current_relative_path) 1272 | if [[ "$path" != "$(pwd)" ]] && [[ "$path" != "" ]] ; then 1273 | # we're inside docroot 1274 | cdir="cd $path &&" 1275 | fi 1276 | if [[ "$path" == "" ]] ; then 1277 | # we're on project folder level (outside docroot) 1278 | cdir="cd docroot &&" 1279 | fi 1280 | fi 1281 | 1282 | local columns 1283 | if is_tty ; then 1284 | columns="export COLUMNS=$(tput cols) &&" 1285 | fi 1286 | 1287 | cmd="$cdir $columns" 1288 | 1289 | # 3) convert array of parameters into escaped string 1290 | # Escape spaces that are "spaces" and not parameter delimeters (i.e. param1 param2\ with\ spaces param3) 1291 | if [[ $2 != "" ]]; then 1292 | cmd="$cmd "$(printf " %q" "$@") 1293 | # Do not escape spaces if there is only one parameter (e.g. dsh run "ls -la | grep txt") 1294 | else 1295 | cmd="$cmd $@" 1296 | fi 1297 | 1298 | # 4) execute 1299 | if is_tty ; then 1300 | # interactive 1301 | if [[ $1 == "" ]]; then 1302 | $winpty_cmd docker exec -it $container_id bash -i 1303 | else 1304 | $winpty_cmd docker exec -it $container_id bash -ic "$cmd" 1305 | fi 1306 | else 1307 | # non-interactive 1308 | docker exec $container_id bash -c "$cmd" 1309 | fi 1310 | } 1311 | 1312 | # start interactive mysql shell 1313 | mysql () 1314 | { 1315 | check_dsh_environment 1316 | check_drush_path 1317 | _run $(get_mysql_connect)" -A" # -A option to speed up mysql load 1318 | } 1319 | 1320 | # Truncate db and import from sql dump 1321 | # @param $1 filename of backup file. Should be inside project root 1322 | mysql_import () 1323 | { 1324 | check_dsh_environment 1325 | check_drush_path 1326 | 1327 | local confirm=1 1328 | if [[ "$1" == "-y" ]] || [[ "$2" == "-y" ]]; then 1329 | confirm=0 1330 | if [[ "$1" == "-y" ]]; then 1331 | shift #remove this param if -y was first 1332 | fi 1333 | fi 1334 | 1335 | project_root=$(get_yml_path) 1336 | local filename=$(basename $1) 1337 | local filepath=$(get_abs_path $1) 1338 | #substract project root path from filepath 1339 | local pathdiff=${filepath#$project_root} 1340 | 1341 | if [[ $pathdiff == $filepath ]] ; then 1342 | # substraction did not succeed because file is outside project root 1343 | echo "\"$filename\" should be inside your project root folder" 1344 | return 1345 | fi 1346 | 1347 | if [ $confirm -eq 1 ]; then 1348 | _confirm "[!] This will drop the existing database. Continue?" 1349 | fi 1350 | 1351 | #_run drush sql-drop -y 1352 | local sql_connect 1353 | sql_connect=$(get_mysql_connect) 1354 | echo "Importing $filename into the database..." 1355 | 1356 | # Use pv for interactive shells only. 1357 | if is_tty ; then 1358 | # Check if we have a gzipped dump and treat it differently. 1359 | if [[ $filename == *.gz ]]; then 1360 | file_size=$(gzip -l $1 | sed -n 2p | awk '{print $2}') 1361 | RUN_NO_CDIR=1 _run "zcat ./$pathdiff/$filename | pv --size $file_size | $sql_connect" 1362 | else 1363 | RUN_NO_CDIR=1 _run "pv ./$pathdiff/$filename | $sql_connect" 1364 | fi 1365 | else 1366 | # Check if we have a gzipped dump and treat it differently. 1367 | if [[ $filename == *.gz ]]; then 1368 | RUN_NO_CDIR=1 _run "zcat ./$pathdiff/$filename | $sql_connect" 1369 | else 1370 | RUN_NO_CDIR=1 _run "cat ./$pathdiff/$filename | $sql_connect" 1371 | fi 1372 | fi 1373 | 1374 | # Check if import succeded or not and print results. 1375 | if [ $? -eq 0 ]; then 1376 | echo-green "dsh: mysql-import finished"; 1377 | if is_tty; then _notify "Dsh" "Mysql import finished"; fi 1378 | else 1379 | echo-red "dsh: mysql-import failed"; 1380 | if is_tty; then _notify "Dsh" "Mysql import failed!"; fi 1381 | fi 1382 | } 1383 | 1384 | # Shortcut to run drush cc ... on site 1385 | # @param $1 type of cache to clean (all, css-js, ...) 1386 | clear_cache () 1387 | { 1388 | check_dsh_environment 1389 | local type='all' 1390 | if [[ ! "$1" == "" ]]; then 1391 | type=$1 1392 | fi 1393 | 1394 | _run "drush cc $type" 1395 | } 1396 | 1397 | # Run Behat tests (also install dependencies through Composer) 1398 | # @param $* arguments and params passed to Behat 1399 | behat () 1400 | { 1401 | check_dsh_environment 1402 | cd $(get_yml_path) 1403 | 1404 | local params='' 1405 | local path='tests/behat' 1406 | for i in "$@"; do 1407 | case $i in 1408 | --path=*) 1409 | path="${i#*=}" 1410 | ;; 1411 | *) 1412 | params="$params$i " 1413 | ;; 1414 | esac; 1415 | done 1416 | 1417 | local project_root_path=$(get_yml_path) 1418 | local behat_yml_path="${project_root_path}/${path}/behat.yml" 1419 | if [[ ! -f "${behat_yml_path}" ]]; then 1420 | echo-red "Could not find ${behat_yml_path}" 1421 | exit 1 1422 | fi 1423 | _run "cd $path && composer install --prefer-source --no-interaction" 1424 | _run "cd $path && bin/behat -p docker $params" 1425 | } 1426 | 1427 | # Download script by URL and execute it 1428 | # @param $1 url of script. 1429 | exec_url () 1430 | { 1431 | if [[ "$1" != "" ]]; then 1432 | local script 1433 | script=$(curl -kfsSL "$1") 1434 | if_failed "Failed downloading script $1" 1435 | bash <(echo "$script") 1436 | else 1437 | echo-red "URL is required" 1438 | fi 1439 | } 1440 | 1441 | # Remove container(s) 1442 | # @param $1 $2... container names 1443 | remove () 1444 | { 1445 | check_dsh_environment 1446 | if [[ $1 == "" ]]; then 1447 | echo -e "${red}WARNING:${NC} ${yellow}You have chosen to delete or re-create all project containers.${NC}" 1448 | _confirm "Continue?"; 1449 | fi 1450 | 1451 | # support quiet removal 1452 | if [[ $1 == "-f" ]]; then 1453 | shift 1454 | fi 1455 | 1456 | _remove_containers $* 1457 | } 1458 | 1459 | # Reset container(s) (stop, remove, up) 1460 | # @param $1 $2... containers names 1461 | reset () 1462 | { 1463 | check_docker_running 1464 | 1465 | if [[ "$1" == "proxy" ]] ; then 1466 | echo-green 'Resetting Drude HTTP/HTTPS reverse proxy service...' 1467 | install_proxy_service 1468 | return 1469 | fi 1470 | 1471 | if [[ "$1" == "dns" ]] ; then 1472 | echo-green 'Resetting Drude DNS service...' 1473 | install_dns_service 1474 | return 1475 | fi 1476 | 1477 | if [[ "$1" == "ssh-agent" ]] ; then 1478 | echo-green 'Resetting Drude ssh-agent service...' 1479 | install_sshagent_service 1480 | return 1481 | fi 1482 | 1483 | if [[ "$1" == "system" ]] ; then 1484 | echo-green 'Resetting Drude services...' 1485 | echo 'vhost-proxy' 1486 | install_proxy_service 1487 | echo 'dns' 1488 | install_dns_service 1489 | echo 'ssh-agent' 1490 | install_sshagent_service 1491 | return 1492 | fi 1493 | 1494 | check_yml 1495 | # support quiet removal 1496 | if [[ $1 == "-f" ]]; then 1497 | shift 1498 | remove -f "$*" 1499 | else 1500 | remove "$*" 1501 | fi 1502 | _start_containers 1503 | } 1504 | 1505 | # Show logs 1506 | # @param $* container(s) name 1507 | logs () 1508 | { 1509 | docker_compose logs $* 1510 | } 1511 | 1512 | # Set uid of the primary "docker" user in the cli container 1513 | # Useful to match the host uid with the uid in the cli container and avoid file permission issues this way. 1514 | _set_cli_uid () 1515 | { 1516 | if [[ $DRUDE_SET_UID == "" ]] ; then 1517 | DRUDE_SET_UID=$(id -u) 1518 | fi 1519 | # Let uid to be set with the DRUDE_SET_UID env variable 1520 | if [[ $DRUDE_SET_UID != 0 ]] ; then 1521 | local host_uid=$DRUDE_SET_UID 1522 | local container_uid=$(docker exec $(get_container_id cli) id -u) 1523 | 1524 | if [[ $container_uid != $host_uid ]]; then 1525 | echo-green "Changing user uid in cli from $container_uid to $host_uid..." 1526 | docker exec -u root $(get_container_id cli) usermod -u $host_uid docker 1527 | echo-green "Reseting permissions on /var/www..." 1528 | docker exec -u root $(get_container_id cli) chown -R docker:users /var/www 1529 | echo-green "Restarting php daemon..." 1530 | # TODO: Remove. This code is to support legacy cli image version, where php5-fpm service name was used. 1531 | local php_service='php-fpm'; 1532 | local local res=$(docker exec $(get_container_id cli) grep "program:php5-fpm" /etc/supervisor/conf.d/supervisord.conf) 1533 | if [[ "$res" != '' ]]; then php_service='php5-fpm'; fi 1534 | docker exec -u root $(get_container_id cli) supervisorctl restart $php_service 1535 | else 1536 | echo-green "Container and host uids already match ($container_uid)." 1537 | fi 1538 | else 1539 | echo-yellow "Running Drude as root is not recommended. Please run as a regular user with docker access." 1540 | fi 1541 | } 1542 | 1543 | _system_information_heading () 1544 | { 1545 | local dashes_length=$((32+${#1})) 1546 | echo 1547 | printf '–%.0s' $(seq 1 $dashes_length) 1548 | echo 1549 | echo " $1" 1550 | printf '–%.0s' $(seq 1 $dashes_length) 1551 | echo 1552 | } 1553 | 1554 | system_information () 1555 | { 1556 | _system_information_heading "OS" 1557 | uname -a 1558 | if is_linux; then 1559 | [ -f /etc/os-release ] && cat /etc/os-release 1560 | [ -f /etc/system-release ] && cat /etc/system-release 1561 | fi 1562 | echo -n "Current dir: " 1563 | pwd 1564 | 1565 | _system_information_heading "Dsh" 1566 | version 1567 | 1568 | _system_information_heading "Docker" 1569 | echo "DOCKER_HOST: $DOCKER_HOST" 1570 | echo 1571 | docker version 1572 | 1573 | _system_information_heading "Docker Compose" 1574 | docker-compose version 1575 | 1576 | if ! is_linux; then 1577 | _system_information_heading "VirtualBox" 1578 | VBoxManage --version 1579 | 1580 | _system_information_heading "Running Virtual Boxes" 1581 | VBoxManage list runningvms 1582 | 1583 | _system_information_heading "VirtualBox Network interfaces" 1584 | VBoxManage list hostonlyifs 1585 | 1586 | _system_information_heading "Vagrant" 1587 | vagrant --version 1588 | 1589 | _system_information_heading "Vagrant Box version" 1590 | local vagrant_path=$(upfind Vagrantfile) 1591 | if [[ $vagrant_path == "" ]]; then 1592 | echo "Vagrantfile not found" 1593 | else 1594 | cat $vagrant_path/Vagrantfile | grep box_version 1595 | fi 1596 | 1597 | if [[ $vagrant_path != "" ]]; then 1598 | _system_information_heading "Vagrant Boxes List" 1599 | vagrant global-status 1600 | fi 1601 | fi 1602 | 1603 | echo 1604 | } 1605 | 1606 | if [[ "$*" != "update dsh" ]]; then 1607 | check_for_updates 1608 | fi 1609 | # Command bindings 1610 | argv="$@" 1611 | case $1 in 1612 | up) 1613 | up 1614 | ;; 1615 | start) 1616 | up 1617 | ;; 1618 | stop) 1619 | shift 1620 | down $* 1621 | ;; 1622 | down) 1623 | shift 1624 | down $* 1625 | ;; 1626 | halt) 1627 | halt 1628 | ;; 1629 | restart) 1630 | shift 1631 | restart $* 1632 | ;; 1633 | reload) 1634 | reload 1635 | ;; 1636 | status) 1637 | shift 1638 | status $* 1639 | ;; 1640 | st) 1641 | shift 1642 | status $* 1643 | ;; 1644 | ps) 1645 | shift 1646 | status $* 1647 | ;; 1648 | vmstat) 1649 | vmstat 1650 | ;; 1651 | ssh-add) 1652 | shift 1653 | ssh_add "$*" 1654 | ;; 1655 | install) 1656 | shift 1657 | install $* 1658 | ;; 1659 | update) 1660 | shift 1661 | if [[ "$1" == "prerequisites" ]]; then 1662 | install_prerequisites 1663 | elif [[ "$1" == "boot2docker" ]]; then 1664 | update_boot2docker $* 1665 | elif [[ "$1" == "images" ]]; then 1666 | update_images 1667 | elif [[ "$1" == "dsh" ]]; then 1668 | update_dsh 1669 | else 1670 | echo "Use dsh update [prerequisites|boot2docker|images|dsh]" 1671 | fi 1672 | ;; 1673 | self-update) 1674 | update_dsh 1675 | ;; 1676 | bash) 1677 | shift 1678 | _bash $* 1679 | ;; 1680 | exec) 1681 | shift 1682 | _run "$@" 1683 | ;; 1684 | run) 1685 | shift 1686 | _run "$@" 1687 | ;; 1688 | mysql) 1689 | mysql 1690 | ;; 1691 | sqlc) 1692 | mysql 1693 | ;; 1694 | mysql-import) 1695 | mysql_import $2 $3 1696 | ;; 1697 | sqli) 1698 | mysql_import $2 $3 1699 | ;; 1700 | cc) 1701 | clear_cache $2 1702 | ;; 1703 | drush) 1704 | shift 1705 | if [[ $1 == "" ]]; then 1706 | _run drush 1707 | else 1708 | _run drush "$@" 1709 | fi 1710 | ;; 1711 | drupal) 1712 | shift 1713 | if [[ "$1" == "" ]]; then 1714 | _run drupal 1715 | else 1716 | _run drupal "$@" 1717 | fi 1718 | ;; 1719 | behat) 1720 | shift 1721 | behat "$@" 1722 | ;; 1723 | exec-url) 1724 | shift 1725 | exec_url "$*" 1726 | ;; 1727 | reset) 1728 | shift 1729 | reset $* 1730 | ;; 1731 | remove) 1732 | shift 1733 | remove $* 1734 | ;; 1735 | cleanup) 1736 | shift 1737 | _docker_cleanup $1 1738 | ;; 1739 | -v | v) 1740 | version --short 1741 | ;; 1742 | version) 1743 | version 1744 | ;; 1745 | bash_comp_words) 1746 | shift 1747 | bash_comp_words "$*" 1748 | ;; 1749 | logs) 1750 | shift 1751 | logs $@ 1752 | ;; 1753 | "") 1754 | show_help 1755 | ;; 1756 | help) 1757 | show_help $2 1758 | ;; 1759 | system-info | sysinfo) 1760 | system_information 1761 | ;; 1762 | init|*) 1763 | # Search for custom commands in $DRUDE_COMMANDS_PATH 1764 | 1765 | legacy_init_path="$(get_drude_path)/.drude/scripts/drude-init.sh" 1766 | if [[ "$1" == "init" ]] && [[ -f $legacy_init_path ]]; then 1767 | # Legacy processing for init script 1768 | dsh_command_script=$legacy_init_path 1769 | else 1770 | # Normal search for custom command 1771 | dsh_command_script="$(get_drude_path)/$DRUDE_COMMANDS_PATH/$1" 1772 | fi 1773 | 1774 | if [ -f "$dsh_command_script" ]; then 1775 | if [[ ! -x "$dsh_command_script" ]]; then 1776 | echo -e "${yellow}$dsh_command_script${NC} is not set to be executable." 1777 | _confirm "Fix automatically?" 1778 | chmod +x "$dsh_command_script" 1779 | if_failed "Could not make $dsh_command_script executable" 1780 | fi 1781 | shift 1782 | export YML_PATH="$(get_yml_path)" 1783 | export DRUDE_PATH="$(get_drude_path)" 1784 | export PROJECT_ROOT="$(get_drude_path)" 1785 | if is_docker_running; then 1786 | export DOCKER_RUNNING="true" 1787 | else 1788 | export DOCKER_RUNNING="false" 1789 | fi 1790 | 1791 | exec "$dsh_command_script" "$@" 1792 | else 1793 | echo-yellow "dsh: unknown command '"$*"'. See 'dsh help' for list of available commands" 1794 | exit 1 1795 | fi 1796 | esac 1797 | -------------------------------------------------------------------------------- /bin/dsh-bash-complete: -------------------------------------------------------------------------------- 1 | _dsh_completion() 2 | { 3 | local cur=${COMP_WORDS[COMP_CWORD]} #current word part 4 | local prev=${COMP_WORDS[COMP_CWORD-1]} #previous word 5 | local compwords=$(dsh bash_comp_words $prev) #get completions for previous word 6 | if [ ! $? -eq 0 ]; then 7 | return 1; 8 | else 9 | COMPREPLY=( $(compgen -W "$compwords" -- $cur) ) 10 | return 0 11 | fi 12 | } 13 | complete -o bashdefault -o default -F _dsh_completion dsh 14 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Docker and Docker Compose based environment for Drupal. 2 | # See https://github.com/blinkreaction/drude for more information and documentation. 3 | 4 | # Web node 5 | web: 6 | hostname: web 7 | image: blinkreaction/drupal-apache:2.2-stable 8 | ports: 9 | - "80" 10 | - "443" 11 | # Use IP based mapping when working with multiple projects. See docs (^^) for more details. 12 | #- 192.168.10.10:80:80 13 | #- 192.168.10.10:443:443 14 | volumes: 15 | # Project root folder mapping 16 | - &project_root ".:/var/www" 17 | links: 18 | - cli 19 | environment: 20 | - VIRTUAL_HOST=hello-world.drude 21 | 22 | # DB node 23 | db: 24 | hostname: db 25 | image: blinkreaction/drupal-mysql:5.5 26 | ports: 27 | - "3306" 28 | # Use IP based mapping when working with multiple projects. See docs (^^) for more details. 29 | #- 192.168.10.10:3306:3306 30 | # DB configuration 31 | environment: 32 | - MYSQL_ROOT_PASSWORD=admin123 33 | - MYSQL_USER=drupal 34 | - MYSQL_PASSWORD=123 35 | - MYSQL_DATABASE=drupal 36 | volumes: 37 | # MySQL configuration overrides 38 | - "./.drude/etc/mysql/my.cnf:/etc/mysql/conf.d/z_my.cnf" 39 | 40 | # CLI node 41 | # Used for all console commands and tools. 42 | cli: 43 | hostname: cli 44 | image: blinkreaction/drupal-cli:stable 45 | volumes: 46 | # Project root folder mapping 47 | - *project_root 48 | # PHP FPM configuration overrides 49 | - "./.drude/etc/php5/php.ini:/etc/php5/fpm/conf.d/z_php.ini" 50 | # PHP CLI configuration overrides 51 | - "./.drude/etc/php5/php-cli.ini:/etc/php5/cli/conf.d/z_php.ini" 52 | # Host home directory mapping (for SSH keys and ther credentials). 53 | # We try to map both options (b2d and Linux). The startup.sh script in cli container will decide which one to use. 54 | - /.home:/.home-b2d # boot2docker-vagrant 55 | - ~:/.home-linux # Linux 56 | links: 57 | - db 58 | environment: 59 | # Optional. Specify a custom SSH RSA key name if necessary. Defaults to 'id_rsa'. 60 | - SSH_KEY_NAME=id_rsa 61 | # Uncomment the next 2 lines to use the shared ssh-agent. 62 | # volumes_from: 63 | # - ssh-agent 64 | 65 | # Memcached node 66 | # Uncomment the service definition section below to start using memcached. 67 | # memcached: 68 | # hostname: memcached 69 | # image: memcached 70 | # environment: 71 | # # Memcached memory limit in megabytes 72 | # - MEMCACHED_MEMORY_LIMIT=128 73 | # - DOMAIN_NAME=memcached.hello-world.docker 74 | 75 | # ngrok node 76 | # Uncomment the service definition section below to start using ngrok for sharing your local web server with the world. 77 | # share: 78 | # hostname: share 79 | # image: fnichol/ngrok 80 | # ports: 81 | # - "4040" 82 | # # Use IP based mapping when working with multiple projects. See docs (^^) for more details. 83 | # #- 192.168.10.10:4040:4040 84 | # links: 85 | # - web:http 86 | 87 | # Selenium2 node 88 | # Uncomment the service definition section below to start using selenium2 driver for Behat tests requiring JS support. 89 | # browser: 90 | # hostname: browser 91 | # image: selenium/standalone-chrome 92 | # ports: 93 | # - "4444" 94 | # environment: 95 | # - DOMAIN_NAME=browser.hello-world.docker 96 | 97 | # Solr node 98 | # Uncomment the service definition section below to start using Solr. 99 | # solr: 100 | # hostname: solr 101 | # image: blinkreaction/drupal-solr:3.x-stable 102 | # # Mapping for custom Solr configuration. 103 | # # See https://github.com/blinkreaction/docker-drupal-solr/tree/master/solr3.x/solr/conf for the default one. 104 | # #volumes: 105 | # # - "./.drude/etc/solr:/var/lib/solr/conf" 106 | # environment: 107 | # - DOMAIN_NAME=solr.hello-world.docker 108 | -------------------------------------------------------------------------------- /docs/apache-solr.md: -------------------------------------------------------------------------------- 1 | # Enabling Apache Solr service 2 | 3 | ## DDE configuration 4 | 5 | 1. Add Apache Solr service to `docker-compose.yml`: 6 | 7 | Replace `` with your project name. 8 | 9 | ```yml 10 | # Solr node 11 | # Uncomment the service definition section below to start using Solr. 12 | solr: 13 | hostname: solr 14 | image: blinkreaction/drupal-solr:3.x-stable 15 | environment: 16 | - DOMAIN_NAME=solr..drude 17 | ``` 18 | 19 | 2. Apply new configuration with `dsh up` 20 | 21 | ## Drupal configuration 22 | 23 | 1. Enable all required Drupal modules for Solr search integration on your site 24 | 25 | 2. Add your Solr server on page `admin/config/search/apachesolr/settings/add` with following server url: 26 | 27 | Solr server URL: `http://solr..drude:8983/solr` 28 | -------------------------------------------------------------------------------- /docs/behat.md: -------------------------------------------------------------------------------- 1 | # Using Behat 2 | 3 | ## Expected folder structure 4 | 5 | DDE expects your Behat tests to be in `tests/behat` folder of the project repo. 6 | 7 | > tests/behat 8 | > \_ bin/behat 9 | > \_ behat.yml 10 | > \_ composer.json 11 | > \_ composer.lock 12 | 13 | See [Drupal 7 sample project](https://github.com/blinkreaction/drude-d7-testing) repo for a working example. 14 | 15 | ## Docker profile example 16 | 17 | Assuming you are using [Behat Drupal Extension](https://github.com/jhedstrom/drupalextension) add the following profile in your `behat.yml` file: 18 | 19 | ```yml 20 | # Docker profile. 21 | # For use inside the CLI container in DDE. 22 | docker: 23 | extensions: 24 | Behat\MinkExtension: 25 | # URL of the site when accessed inside DDE. 26 | base_url: http://hello-world.drude 27 | selenium2: 28 | wd_host: http://browser.hello-world.docker:4444/wd/hub 29 | # Stick with chrome by default. It's 2x faster than firefox or phantomjs (your results may vary). 30 | browser_name: chrome 31 | Drupal\DrupalExtension: 32 | drupal: 33 | # Site docroot inside DDE. 34 | drupal_root: /var/www/docroot 35 | drush: 36 | # Site docroot inside DDE. 37 | root: /var/www/docroot 38 | ``` 39 | 40 | This will configure Behat for use with DDE. 41 | 42 | **Important note** 43 | 44 | `base_url: http://hello-world.drude` and `wd_host: http://browser.hello-world.docker:4444/wd/hub` 45 | should be configured based on your `docker-compose.yml` settings for `VIRTUAL_HOST` 46 | in the web container definition and `DOMAIN_NAME` in the browser container definition. 47 | 48 | ## Running tests 49 | 50 | Tests can be launched with `dsh` (DDE Shell): 51 | 52 | dsh behat 53 | 54 | This will download composer dependencies and run behat with the docker profile. 55 | 56 | ## Behat (goutte-driver) 57 | 58 | Basic configuration (see [behat.common.yml](https://github.com/blinkreaction/drude-d7-testing/blob/master/tests/behat/behat.common.yml)) uses goutte as the default driver. Goutte is a very basic browser emulator. It is much faster than real browsers, but also very limited. It can make HTTP requests, but does not parse CSS, execute JS or do any rendering. 59 | 60 | Goutte can be used in many cases and does not require additional configuration/installation. 61 | 62 | ## Behat (selenium2-driver) 63 | 64 | If your tests require javascript support, selenium2-driver should be used. You can set selenium2-driver as the default one. 65 | Selenium2 works with real browsers, using them as zombies for testing purposes. You get a standard, feature reach, real browser, with CSS styling, JS and AJAX execution - all supported out of the box. 66 | 67 | The easiest way to enable Selenium support is to use stock Selenium docker images. 68 | To do this, update `docker-compose.yml` file in your project folder as follows. 69 | 70 | ```yml 71 | # selenium2 node 72 | # Uncomment the service definition section below and the link in the web service above to start using selenium2 driver for Behat tests requiring JS support. 73 | browser: 74 | hostname: browser 75 | image: selenium/standalone-chrome 76 | ports: 77 | - "4444" 78 | environment: 79 | - DOMAIN_NAME=drude-d7-testing.browser.docker 80 | ``` 81 | 82 | You can also use Firefox image: `selenium/standalone-firefox` 83 | 84 | After updating `docker-compose.yml` you have to tell Behat to use Selenium. 85 | Add your selenium configuration in `behat.yml` (environment variable `DOMAIN_NAME` is used as `selenium2 wd_host`). 86 | 87 | Example: 88 | 89 | ```yml 90 | # Docker profile. 91 | # For use inside the CLI container in DDE. 92 | docker: 93 | extensions: 94 | Behat\MinkExtension: 95 | # URL of the site when accessed inside DDE. 96 | base_url: http://drupal7.drude 97 | selenium2: 98 | wd_host: http://drude3-d7-testing.browser.docker:4444/wd/hub 99 | # Stick with chrome by default. It's 2x faster than firefox or phantomjs (your results may vary). 100 | browser_name: chrome 101 | Drupal\DrupalExtension: 102 | drupal: 103 | # Site docroot inside DDE. 104 | drupal_root: /var/www/docroot 105 | drush: 106 | # Site docroot inside DDE. 107 | root: /var/www/docroot 108 | ``` 109 | 110 | ## Behat (selenium2-driver) - using VNC 111 | 112 | If you use Selenium with a browser in a container, you can receive test screenshots but you cannot see the browser itself. Sometimes it is very useful to watch tests running in the browser (e.g. when you are creating a new test and want to see how it performs). 113 | In such cases [VNC](https://en.wikipedia.org/wiki/Virtual_Network_Computing) can be used. 114 | 115 | 1. Install VNC client on your computer (there are many version for all platforms). 116 | 2. Update `docker-compose.yml` file in your project folder: 117 | 118 | ```yml 119 | # selenium2 node 120 | # Uncomment the service definition section below and the link in the web service above to start using selenium2 driver for Behat tests requiring JS support. 121 | browser: 122 | hostname: browser 123 | image: selenium/standalone-chrome-debug 124 | ports: 125 | - "4444" 126 | - "5900:5900" 127 | environment: 128 | - DOMAIN_NAME=drude-d7-testing.browser.docker 129 | ``` 130 | You have to use `selenium/standalone-chrome-debug` or `selenium/standalone-firefox-debug` images. They both include a VNC server. 131 | Use `localhost:5900` as the host and `secret` as the password in your VNC client. 132 | Now if you connect with the VNC client and run behat test, you will be able to see tests running in the browser inside the container. 133 | 134 | Note: If you are working with several project concurrently, it is a good idea to have a separate port per project (e.g. `5901:5900`, `5902:5900`, etc.) 135 | 136 | ## Integration with PhpStorm 137 | 138 | It is possible to connect PhpStorm with the `cli` container and run behat tests from within PhpStorm. 139 | PhpStorm uses ssh to connect to and use remote interpreters and tools. 140 | 141 | 1. Add the following line in `docker-compose.yml` to expose ssh-server in the `cli`container: 142 | 143 | ```yml 144 | cli: 145 | ... 146 | ports: 147 | - "2221:22" 148 | ... 149 | ``` 150 | 2. Update container configuration with `dsh up`. 151 | 3. You should now be able to connect to the `cli` container via ssh. Use username `docker` and pasword `docker`: 152 | 153 | ``` 154 | ssh docker@localhost -p 2223 155 | ``` 156 | 157 | Note: If you are working with several project concurrently, it is a good idea to have a separate port per project (e.g. `2222:22`, `2223:22`, etc.) 158 | 159 | ### Add new deployment server 160 | 161 | Open settings (menu item *File->Settings...*). In the opened window on the left side select item *Build, Execution, Deployment->Deployment*: 162 | 163 | ![](img/behat-phpstorm-deployment-configure.png) 164 | 165 | Create new SFTP connection and fill-out the form. Don't forget to fill-out *Web server root URL*. 166 | Press *Test SFTP connection...* button and if everything is ok, you will see that test is successful. 167 | 168 | On the second tab you should to check and correct mapping: 169 | 170 | ![](img/behat-phpstorm-deployment-configure-mapping.png) 171 | 172 | Local path is path to your project on the host machine. Deployment path is `/var/www` 173 | 174 | ### Add a new PHP interpreter 175 | 176 | Open settings (menu item *File->Settings...*). In the opened window on the left side select item *Languages & Frameworks->PHP*: 177 | 178 | ![](img/behat-phpstorm-PHP-configuration.png) 179 | 180 | To add a new interpreter click on **...** button on *Interpreter:* line. 181 | 182 | ![](img/behat-phpstorm-PHP-configuration-deployment.png) 183 | 184 | In the opened window add a new interpreter and choose **Deployment configuration** option and deployment server from select list (it should be server from previous step). 185 | 186 | ### Add Behat interpreter configuration 187 | 188 | Open settings (menu item *File->Settings...*). In the opened window on the left side select item *Languages & Frameworks->PHP->Behat*: 189 | 190 | ![](img/behat-phpstorm-PHP-Behat-configuration.png) 191 | 192 | Add a new PHP interpreter for Behat (it should be the interpreter from previous step). 193 | 194 | Path to Behat is the path in the `cli` container - ``/var/www/tests/behat/bin/behat` 195 | 196 | Default configuration file: `/var/www/tests/behat/behat.yml` 197 | 198 | Check that your `behat.yml` contains `wd_host` for selenium in `Behat\MinkExtension` part: 199 | 200 | ![](img/behat-behat-yml.png) 201 | 202 | It should be the same as in `behat.common.yml` for `docker` part. 203 | 204 | ### Add Behat debug configuration 205 | 206 | Open *Run/Debug Configurations* (menu item *Run->Edit Configurations...*). In the opened window on the left side add new Behat configuration: 207 | 208 | ![](img/behat-run-debug-configuration.png) 209 | 210 | Choose Test Runner option *Defined in the configuration file*. 211 | 212 | Or you can choose `behat.yml` from your host machine (use *File* option in this case). It makes no difference. 213 | 214 | ### Run tests 215 | 216 | On the PhpStorm panel choose Behat debug configuration and run it: 217 | 218 | ![](img/behat-run-tests.png) 219 | 220 | If everything is ok, you will see a window with tests result (all tests are run in this case): 221 | 222 | ![](img/behat-run-window.png) 223 | 224 | You can re-run any scenario from this window. If you click on scenario or test, PhpStorm will open window with this scenario/test. 225 | 226 | You can also open folder with Behat features (`tests/behat/features` directory in your project) and 227 | run any feature tests by right clicking on it and choosing **Run 'feature-name'** option. 228 | 229 | ![](img/behat-test-features.png) 230 | 231 | #### Known issue 232 | On this step you can see an error: 233 | 234 | > [PDOException] 235 | > SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) 236 | 237 | In this case check Drupal `settings.php`. Please don't use variables for DB settings: 238 | ```PHP 239 | # DDE DB connection settings. 240 | $databases['default']['default'] = array ( 241 | 'database' => getenv('DB_1_ENV_MYSQL_DATABASE'), 242 | 'username' => getenv('DB_1_ENV_MYSQL_USER'), 243 | 'password' => getenv('DB_1_ENV_MYSQL_PASSWORD'), 244 | 'host' => getenv('DB_1_PORT_3306_TCP_ADDR'), 245 | 'driver' => 'mysql', 246 | ); 247 | ``` 248 | 249 | Use only values - something like this: 250 | 251 | ```PHP 252 | # DDE DB connection settings. 253 | $databases['default']['default'] = array ( 254 | 'database' => 'drupal', 255 | 'username' => 'drupal', 256 | 'password' => '123', 257 | 'host' => 'db', 258 | 'driver' => 'mysql', 259 | ); 260 | ``` 261 | 262 | ## Using host selenium2-driver 263 | 264 | You can use selenium from your host machine instead of the selenium in a container. 265 | 266 | Selenium Standalone Server is available [here](http://www.seleniumhq.org/download/). 267 | WebDriver for Chrome is available [here](https://sites.google.com/a/chromium.org/chromedriver/downloads). 268 | 269 | Run selenium with Chrome webdriver: 270 | 271 | > java -jar selenium-server-standalone-2.53.0.jar -Dwebdriver.chrome.driver=/path/to/webdriver/chromedriver 272 | 273 | By default it is running on port `4444`, which can be verified by openning `http://localhost:4444/wd/hub/static/resource/hub.html` in a browser. 274 | 275 | Update `behat.yml` (set `wd_host` to point to the host machine): 276 | 277 | ```yml 278 | # Local overrides to the default profile 279 | default: 280 | extensions: 281 | Behat\MinkExtension: 282 | # URL of the site when accessed locally. 283 | base_url: http://drupal7.drude 284 | # Configure browser to be used. Browser must be available on wd_host. 285 | browser_name: chrome 286 | selenium2: 287 | wd_host: http://192.168.10.1:4444/wd/hub/static/resource/hub 288 | ... 289 | ``` 290 | 291 | `192.168.10.1` is your machine's IP in DDE subnet. 292 | 293 | If you use host selinium driver, please don't use selenium2 node - check and comment `browser` container config in your docker-compose.yml file: 294 | 295 | ```yml 296 | # selenium2 node 297 | # Uncomment the service definition section below and the link in the web service above to start using selenium2 driver for Behat tests requiring JS support. 298 | #browser: 299 | # hostname: browser 300 | # image: selenium/standalone-chrome 301 | # ports: 302 | # - "4444" 303 | # environment: 304 | # - DOMAIN_NAME=drude-d7-testing.browser.docker 305 | ``` 306 | 307 | If you use host selinium driver and selenium from docker container, behat will use configuration from `docker:` part of `behat.common.yml` instead of `default:` part in `behat.yml`. And it will not work. -------------------------------------------------------------------------------- /docs/blackfire.md: -------------------------------------------------------------------------------- 1 | # Using Blackfire profiler 2 | 3 | ## Setup 4 | 5 | 1. Register with https://blackfire.io. 6 | 7 | 2. Add `blackfire` service in `docker-compose.yml` and configure API keys: 8 | 9 | **Option 1:** Use [Blackfire Docker instructions](https://blackfire.io/docs/integrations/docker) to get a snippet that you can put in a `.bash_rc`/etc. file globally. Uncomment respective lines in `docker-compose.yml`. 10 | 11 | **Option 2:** Grab **server** API keys from your [profile page](https://blackfire.io/account). 12 | Uncomment respective lines in `docker-compose.yml` and replace `Server ID` and `Server Token` with your API keys. 13 | 14 | ```yml 15 | blackfire: 16 | image: blackfire/blackfire 17 | environment: 18 | # Option 1: exposes host's BLACKFIRE_SERVER_ID and TOKEN environment variables. 19 | #- BLACKFIRE_SERVER_ID 20 | #- BLACKFIRE_SERVER_TOKEN 21 | # Option 2: use global environment credentials. 22 | #- BLACKFIRE_SERVER_ID= 23 | #- BLACKFIRE_SERVER_TOKEN= 24 | # Log verbosity level (4: debug, 3: info, 2: warning, 1: error). 25 | #- BLACKFIRE_LOG_LEVEL=4 26 | ``` 27 | 28 | 3. For `docker-compose.yml` files using version 1: 29 | 30 | Note: if you do not see `version: 2` in the beginning of your `docker-compose.yml` file, then proceed. 31 | Add a link in the `cli` service definition: 32 | 33 | ```yml 34 | ... 35 | links: 36 | ... 37 | - blackfire 38 | ... 39 | ``` 40 | 41 | 4. Apply new configuration with `dsh up` 42 | 43 | 5. Follow instruction to install and use blackfire via a [Chrome extension](https://blackfire.io/docs/integrations/chrome). 44 | 45 | See [blackfire.io](https://blackfire.io/docs/introduction) for more docs on using blackfire including support for other browsers. 46 | -------------------------------------------------------------------------------- /docs/custom-commands.md: -------------------------------------------------------------------------------- 1 | # DSH custom commands 2 | 3 | Extending DSH with your custom commands is supported in DSH 1.17 and higher. 4 | 5 | 1. Create a custom command 6 | 7 | File `.drude/commands/updb` (Notice **no extension**. Script name should match command name) 8 | 9 | ```bash 10 | #!/bin/bash 11 | 12 | ## Runs drush updb 13 | ## 14 | ## Usage: dsh updb [params to passthrough] 15 | 16 | dsh drush updb $1 17 | ``` 18 | 19 | 2. Set executable bit: `chmod +x .drude/commands/updb` 20 | 3. Use as regular dsh command: `dsh updb` 21 | 4. Passing parameters also works: `dsh updb -y` 22 | 5. See command description in `dsh help` and command full help via `dsh help updb` 23 | 24 | ## Available variables 25 | 26 | These environment variables are available for use inside you custom command scripts: 27 | 28 | * `DRUDE_PATH` - absolute path to `.drude` folder 29 | * `YML_PATH` - absolute path to `docker-compose.yml`. Usually equals DRUDE_PATH but can be empty is yml is not found. 30 | * `DOCKER_RUNNING` - string values "true" and "false" 31 | 32 | Example `init` command: 33 | 34 | ```bash 35 | #!/usr/bin/env bash 36 | 37 | ## Initialize site 38 | 39 | if [ -z "$YML_PATH"]; then 40 | cp docker-compose.yml.dist docker-compose.yml 41 | fi 42 | 43 | # Start containers 44 | dsh up 45 | # Install site 46 | dsh drush site-install -y --site-name="My Drupal site" 47 | # Get login link 48 | cd docroot 2>dev/null 49 | dsh drush uli 50 | ``` 51 | 52 | ## Documenting custom command 53 | 54 | dsh looks for lines starting with `##` for command documentation. 55 | 56 | ```bash 57 | ## Custom command description 58 | ## Usage: dsh mycommand [--force] 59 | ## Parameters: 60 | ## --force Try really hard 61 | ``` 62 | 63 | dsh will output first line of custom command documentation as a short decription in `dsh help`. 64 | Rest of lines will be available as advanced help via `dsh help command_name` 65 | 66 | See example of command documentation in [phpcs command](../examples/.drude/commands/phpcs) 67 | 68 | ## Advanced use 69 | 70 | It is not imperative to use bash. You can use any interpreter for your custom command scripts 71 | 72 | ```python 73 | #!/usr/bin/env python 74 | print "Custom python command!" 75 | ``` 76 | 77 | ```node 78 | #!/usr/bin/env node 79 | /* 80 | ## Custom node command description 81 | */ 82 | console.log("Custom NodeJS command!") 83 | ``` 84 | 85 | ## More examples 86 | 87 | [Custom command examples](../examples/.drude/commands) 88 | -------------------------------------------------------------------------------- /docs/db-access.md: -------------------------------------------------------------------------------- 1 | # MySQL DB access for external tools 2 | 3 | MySQL port is not exposed in the `db` container by default. 4 | This is done to avoid port conflicts if running multiple DDE powered projects (multisites don't count). 5 | 6 | Add the following lines in the `db` service definition in `docker-compose.yml` to make port **3306** exposed: 7 | 8 | ports: 9 | - "3306:3306" 10 | 11 | Run `dsh up`. 12 | 13 | You will now be able to connect to MySQL in the db container on `192.168.10.10:3306` 14 | 15 | Please keep in mind that two db containers will not be able to use the same port (`3306`) on the host. 16 | To avoid port conflicts with multiple DDE powered projects give each project a unique port assignments. 17 | 18 | **Project 1** 19 | 20 | # DB node 21 | db: 22 | ... 23 | ports: 24 | - "3306:3306" 25 | ... 26 | 27 | MySQL endpoint: `192.168.10.10:3306` 28 | 29 | **Project 2** 30 | 31 | # DB node 32 | db: 33 | ... 34 | ports: 35 | - "3307:3306" 36 | ... 37 | 38 | MySQL endpoint: `192.168.10.10:3307` 39 | 40 | When connecting to the MySQL DB using external tools use the following credentials: 41 | 42 | Username: admin 43 | Password: admin123 (or MYSQL_ROOT_PASSWORD variable in docker-compose.yml) 44 | -------------------------------------------------------------------------------- /docs/db-sandbox.md: -------------------------------------------------------------------------------- 1 | # DB sandbox mode 2 | 3 | In certain cases you may want to have a DB sandbox and mess around with the DB, then roll it back. 4 | Normally this can be achieved by backing up the DB and restoring it from the created DB dump. 5 | With large databases (over 500MB) this operation can take a considerable amount of time (10+ minutes). 6 | 7 | With Docker we can sandbox the DB by creating a reusable docker image from the DB container. 8 | Spinning up such image takes less time than re-importing the DB with MySQL. 9 | 10 | For example, a 2.6GB DB dump file takes 14 minutes to import with MySQL. (Re)launching a docker container from an image with that same imported dump takes only 2 minutes. **Your results may obviously vary.** 11 | 12 | This is an advanced used case, so make sure you have a backup of the database before proceeding. 13 | Follow instructions below to get started. 14 | 15 | ## How it works 16 | 17 | In Docker terminology, a read-only [Layer](https://docs.docker.com/terms/layer/#layer) is called an image. In a traditional setup you would use the stock [mysql image](https://registry.hub.docker.com/_/mysql/) as the base image for your DB container. 18 | 19 | :page_facing_up: docker-compose.yml 20 | ```yml 21 | # DB node 22 | db: 23 | image: mysql:5.5 24 | ... 25 | ``` 26 | 27 | The image never changes. Thanks to [Union File System](https://docs.docker.com/terms/layer/#union-file-system) when process wants to write a file to an image, Docker creates a copy of that file in a new layer (the top-most writeable layer). 28 | 29 | The stock [mysql image](https://registry.hub.docker.com/_/mysql/) defines a data volume (`/var/lib/mysql`). This makes sure the DB data is permanently stored outside of the `db` container on the host and is not lost as the container is (re)launches. 30 | 31 | 32 | 33 | To make the sandbox DB mode possible we have to remove this permanent storage volume from the image (this is done be using a fork of the image), import the DB and commit the container as a new image with `docker commit` command. 34 | The new image will include the base image plus all in-memory changes made i.e. your DB snapshot. It is then used as the base image for the DB node going forward. 35 | 36 | :page_facing_up: docker-compose.yml 37 | ```yml 38 | # DB node 39 | db: 40 | image: mysql_with_my_database:snapshot1 41 | ... 42 | ``` 43 | 44 | 45 | 46 | Now you can do any changes to the database you want and each time after the container is restarted all changes will be lost (as it doesn't have external persistant storage) and you will be back to your base image `mysql_with_my_database:snapshot1`. 47 | 48 | ## Steps 49 | 50 | 1. Create a DB dump 51 | 2. Replace the **db** service base image in `docker-compose.yml` with `blinkreaction/mysql-sandbox` 52 | 3. Reset containers 53 | 54 | `dsh reset` 55 | 56 | 4. Import the DB dump you created in step 1. 57 | 5. Stop and [commit](https://docs.docker.com/reference/commandline/cli/#commit) the **db** service container (this will turn the container into a reusable docker image) 58 | 59 | `docker stop $(docker-compose ps -q db) && docker commit $(docker-compose ps -q db) ` 60 | 61 | Replace `` with any meaningful tag you'd like to use for the image. E.g. `db_backup` or `dbdata/myproject:snapshot1` 62 | 63 | 6. Replace the *db* service base image in `docker-compose.yml` with the selected tag. E.g. `image: dbdata/myproject:snapshot1` 64 | 8. Restart containers 65 | 66 | `dsh up` 67 | 68 | You will now have a sandboxed DB container, which defaults to the DB snapshot you created in step 1 every time the db container is restarted. 69 | 70 | ## Precaution 71 | 72 | In case you have a large database it is not recommended to commit the container that already runs on snaphot Base Image (i.e. creating snapshot on top of snapshot). Every docker image holds all parent images + in-memory changes inside it. Thus, **with every commit the size of the resulting image will increase by full size of the DB, not its delta.** 73 | 74 | In case of small database though it is ok to do that. But please keep in mind there's a limitation on depth of layers which currently equals 120. 75 | 76 | ## Disabling the sandbox mode 77 | 78 | You will need a DB dump to revert to. 79 | Either use the one created before enabling the sandbox mode or take another one while the **db** service contained is still up. 80 | 81 | 1. Revert the changes done to the **db** service in `docker-compose.yml` 82 | 2. Reset containers 83 | 84 | `dsh reset` 85 | 86 | 5. Import the DB dump. 87 | 88 | Now the **db** service container is using a persistent data storage volume (`/var/lib/mysql`). 89 | -------------------------------------------------------------------------------- /docs/dde-env-setup.md: -------------------------------------------------------------------------------- 1 | # DDE environment setup 2 | 3 | **This is a one time setup.** 4 | Once you have a working DDE environment in place, you can use it for all DDE powered projects. 5 | 6 | ## Directory structure 7 | 8 | DDE expects a particular [directory structure](/docs/directory-structure.md). 9 | Please review it before proceeding with the setup. 10 | 11 | ## Windows only 12 | 13 | On Windows you will need a Linux-type shell. 14 | 15 | Install [Babun](http://babun.github.io/) before proceeding and run all commands in it. 16 | Instructions were not tested with other shells on Windows. 17 | 18 | Babun should be installed and run **as a regular user (do not use admin command prompt).** 19 | 20 | ## Setup 21 | 22 | 1. Install `dsh` (DDE Shell) 23 | 24 | ``` 25 | sudo curl -L https://raw.githubusercontent.com/blinkreaction/drude/master/bin/dsh -o /usr/local/bin/dsh 26 | sudo chmod +x /usr/local/bin/dsh 27 | ``` 28 | 29 | 2. Create the `` directory 30 | 31 | E.g. `~/projects` on Mac and Linux: 32 | 33 | ``` 34 | mkdir ~/projects 35 | cd ~/projects 36 | ``` 37 | 38 | `c:\projects` (`/c/projects`) on Windows: 39 | 40 | ``` 41 | mkdir /c/projects 42 | cd /c/projects 43 | ``` 44 | 45 | 3. Install DDE's prerequisites 46 | 47 | Mac and Windows: virtualbox, vagrant, boot2docker-vagrant 48 | Linux: docker, docker-compose 49 | 50 | It is recommended to remove any previous versions of these before proceeding. 51 | 52 | ``` 53 | dsh install prerequisites 54 | dsh install boot2docker 55 | ``` 56 | 57 | On Mac and Windows you should see two files created in the `projects` folder: 58 | 59 | ``` 60 | Vagrantfile 61 | vagrant.yml 62 | ``` 63 | 64 | On Linux there's no need in Vagrant (and VirtualBox), so no additional files are created. 65 | -------------------------------------------------------------------------------- /docs/dde-project-setup.md: -------------------------------------------------------------------------------- 1 | # Configure a project to use DDE 2 | 3 | Initial configuration is done once per project (e.g. by a team lead) and committed into the project repo. 4 | 5 | `docker-compose.yml` file and an optional `.drude` folder are good indicators that a project is using DDE. 6 | 7 | **On Windows** make sure your `projects` folder is **not** inside `%USERPROFILE%/.babun` folder. 8 | 9 | ## Setup 10 | 11 | 1. Edit `settings.php` for your site (see [Drupal settings](/docs/drupal-settings.md)). 12 | 2. Open console (Babun on Windows) and cd into ``. 13 | 3. Install default DDE configuration file (downloads the latest `docker-compose.yml`): 14 | 15 | ``` 16 | dsh install drude-config 17 | ``` 18 | 19 | 4. Update `docker-compose.yml` as necessary. 20 | 21 | 5. Start DDE with: 22 | 23 | ``` 24 | dsh up 25 | ``` 26 | 27 | ## Automate the initialization process 28 | 29 | This is optional, but highly recommended. 30 | 31 | Site provisioning can be automated via a [custom command](custom-commands.md). 32 | E.g. `dsh init` will call `.drude/commands/init`, where you can put project specific initialization tasks like: 33 | 34 | - initialize DDE configuration 35 | - import database or perform a site install 36 | - compile sass 37 | - run update, revert features, clear caches, etc. 38 | - enable/disable modules, update variable values 39 | - run Behat tests 40 | 41 | For a fully working example of a DDE powered project (including `dsh init`) take a look at: 42 | - [Drupal 7 sample project](https://github.com/blinkreaction/drude-d7-testing) 43 | - [Drupal 8 sample project](https://github.com/blinkreaction/drude-d8-testing) 44 | -------------------------------------------------------------------------------- /docs/directory-structure.md: -------------------------------------------------------------------------------- 1 | # Directory structure 2 | 3 | DDE enforces a directory structure where all your projects go into subfolders under the main `` folder. 4 | The `` folder can be arbitrarily located and named. It is best to put it on the fastest drive you have. 5 | 6 | `dsh` will install the necessary boot2docker-vagrant VM files (`Vagrantfile` and `vagrant.yml`) into the `` folder. 7 | 8 | ``` 9 | + ... 10 | - 11 | |--- drupal-site 12 | | docker-compose.yml 13 | | docroot 14 | | ... 15 | | 16 | |--- another-drupal-site 17 | | .drude 18 | | docker-compose.yml 19 | | docroot 20 | | ... 21 | | 22 | |--- Vagrantfile (not needed on Linux) 23 | |--- vagrant.yml (not needed on Linux) 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/drupal-settings.md: -------------------------------------------------------------------------------- 1 | # Drupal settings 2 | 3 | Below you will find instructions on configuring you Drupal project to work with DDE. 4 | Some settings are required, others are optional or enahncements. Please review carefully. 5 | 6 | 7 | # DB connection settings (**required**) 8 | 9 | Containers do not have static IP addresses assigned. DB connection settings can be obtained from the environment variables. 10 | 11 | Below are sample settings for Drupal 7 and Drupal8. 12 | If you change the DB node name in `docker-compose.yml` (e.g. `mysql` instead of `db`) then this has to be updated, since variable names will change as well. 13 | 14 | **Drupal 7 and 8** 15 | 16 | ```php 17 | # DDE DB connection settings. 18 | $databases['default']['default'] = array ( 19 | 'database' => getenv('DB_1_ENV_MYSQL_DATABASE'), 20 | 'username' => getenv('DB_1_ENV_MYSQL_USER'), 21 | 'password' => getenv('DB_1_ENV_MYSQL_PASSWORD'), 22 | 'host' => getenv('DB_1_PORT_3306_TCP_ADDR'), 23 | 'driver' => 'mysql', 24 | ); 25 | ``` 26 | 27 | 28 | ## File permissions fix (**required**) 29 | 30 | With NFS mounts Drupal may complain about files directory not being writable. This is a "false-negative" however can be annoying and break certain things. For a workaround add the following to your setting.php file. 31 | 32 | **Drupal 7** 33 | 34 | ```php 35 | # Workaround for permission issues with NFS shares in Vagrant 36 | $conf['file_chmod_directory'] = 0777; 37 | $conf['file_chmod_file'] = 0666; 38 | ``` 39 | 40 | **Drupal 8** 41 | 42 | ```php 43 | # Workaround for permission issues with NFS shares in Vagrant 44 | $settings['file_chmod_directory'] = 0777; 45 | $settings['file_chmod_file'] = 0666; 46 | ``` 47 | 48 | You may also have to reset permissions on the existing files folder. The following command will recursively set folders to 777 (rwx) and files to 666 (rw) 49 | 50 | ```bash 51 | chmod -R +rwX files 52 | ``` 53 | 54 | 55 | ## Reverse proxy settings (**optional**) 56 | 57 | If using [boot2docker-vagrant](https://github.com/blinkreaction/boot2docker-vagrant), 58 | you are most likely using it's vhost-proxy. In that case add the following to settings.php: 59 | 60 | **Drupal 7** 61 | 62 | ```php 63 | # Reverse proxy configuration (DDE's vhost-proxy) 64 | $conf['reverse_proxy'] = TRUE; 65 | $conf['reverse_proxy_addresses'] = array($_SERVER['REMOTE_ADDR']); 66 | // HTTPS behind reverse-proxy 67 | if ( 68 | isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' && 69 | !empty($conf['reverse_proxy']) && in_array($_SERVER['REMOTE_ADDR'], $conf['reverse_proxy_addresses']) 70 | ) { 71 | $_SERVER['HTTPS'] = 'on'; 72 | // This is hardcoded because there is no header specifying the original port. 73 | $_SERVER['SERVER_PORT'] = 443; 74 | } 75 | ``` 76 | 77 | **Drupal 8** 78 | 79 | ```php 80 | # Reverse proxy configuration (DDE's vhost-proxy) 81 | $settings['reverse_proxy'] = TRUE; 82 | $settings['reverse_proxy_addresses'] = array($_SERVER['REMOTE_ADDR']); 83 | // HTTPS behind reverse-proxy 84 | if ( 85 | isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' && 86 | !empty($settings['reverse_proxy']) && in_array($_SERVER['REMOTE_ADDR'], $settings['reverse_proxy_addresses']) 87 | ) { 88 | $_SERVER['HTTPS'] = 'on'; 89 | // This is hardcoded because there is no header specifying the original port. 90 | $_SERVER['SERVER_PORT'] = 443; 91 | } 92 | ``` 93 | 94 | 95 | ## Memcache settings (**optional**) 96 | 97 | **Drupal 7** 98 | 99 | Add the following lines to `settings.php` to point Drupal to the memcached node. Replace `` with path to [memcache module](https://www.drupal.org/project/memcache) in your project. E.g. `sites/all/modules/contrib/memcache` 100 | 101 | ```php 102 | // Memcache 103 | $conf['cache_backends'][] = '/memcache.inc'; 104 | $conf['cache_default_class'] = 'MemCacheDrupal'; 105 | $conf['cache_class_cache_form'] = 'DrupalDatabaseCache'; 106 | $conf['memcache_servers'] = array( 107 | 'memcached.hello-world.docker:11211' => 'default', 108 | ); 109 | ``` 110 | -------------------------------------------------------------------------------- /docs/img/behat-behat-yml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-behat-yml.png -------------------------------------------------------------------------------- /docs/img/behat-phpstorm-PHP-Behat-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-phpstorm-PHP-Behat-configuration.png -------------------------------------------------------------------------------- /docs/img/behat-phpstorm-PHP-configuration-deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-phpstorm-PHP-configuration-deployment.png -------------------------------------------------------------------------------- /docs/img/behat-phpstorm-PHP-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-phpstorm-PHP-configuration.png -------------------------------------------------------------------------------- /docs/img/behat-phpstorm-deployment-configure-mapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-phpstorm-deployment-configure-mapping.png -------------------------------------------------------------------------------- /docs/img/behat-phpstorm-deployment-configure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-phpstorm-deployment-configure.png -------------------------------------------------------------------------------- /docs/img/behat-run-debug-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-run-debug-configuration.png -------------------------------------------------------------------------------- /docs/img/behat-run-tests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-run-tests.png -------------------------------------------------------------------------------- /docs/img/behat-run-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-run-window.png -------------------------------------------------------------------------------- /docs/img/behat-selenium-container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-selenium-container.png -------------------------------------------------------------------------------- /docs/img/behat-test-features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/behat-test-features.png -------------------------------------------------------------------------------- /docs/img/unionfs-container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/unionfs-container.png -------------------------------------------------------------------------------- /docs/img/unionfs-your-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/unionfs-your-image.png -------------------------------------------------------------------------------- /docs/img/xdebug-mapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/xdebug-mapping.png -------------------------------------------------------------------------------- /docs/img/xdebug-toggle-debugger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/xdebug-toggle-debugger.png -------------------------------------------------------------------------------- /docs/img/xdebug-toggle-listener.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lmakarov/dde/1cb3a24306e35fc2b7bb402fa405068c99993859/docs/img/xdebug-toggle-listener.png -------------------------------------------------------------------------------- /docs/mail.md: -------------------------------------------------------------------------------- 1 | # Sending and capturing email 2 | 3 | Sending/capturing email support can be added via [MailHog](https://github.com/mailhog/MailHog). 4 | 5 | Out-of-the box only capturing will be working. 6 | For email delivery you will have to point MailHog to a working mail server/service. 7 | 8 | ## Setup 9 | 10 | 1. Add the `mail` service in `docker-compose.yml` 11 | 12 | Replace `` with your project name. 13 | 14 | ``` 15 | mail: 16 | hostname: mail 17 | image: mailhog/mailhog 18 | expose: 19 | - "80" 20 | environment: 21 | - MH_API_BIND_ADDR=0.0.0.0:80 22 | - MH_UI_BIND_ADDR=0.0.0.0:80 23 | - DOMAIN_NAME=mail..docker 24 | - VIRTUAL_HOST=webmail..drude 25 | ``` 26 | 27 | Apply new configuration with `dsh up` 28 | 29 | 2. Add to `.drude/etc/php5/php.ini` in the project repo 30 | 31 | Replace `` with your project name. 32 | 33 | ``` 34 | ; Mail settings 35 | sendmail_path = '/usr/local/bin/mhsendmail --smtp-addr=mail..docker:1025' 36 | ``` 37 | 38 | Note: if using `version 2` docker-compose file format, then you may use this instead 39 | 40 | ``` 41 | ; Mail settings 42 | sendmail_path = '/usr/local/bin/mhsendmail --smtp-addr=mail:1025' 43 | ``` 44 | 45 | MailHog web UI will be available at `http://webmail..drude` 46 | -------------------------------------------------------------------------------- /docs/multiple-projects.md: -------------------------------------------------------------------------------- 1 | # Working with multiple projects 2 | 3 | ## Using vhost-proxy (boot2docker-vagrant) 4 | 5 | [boot2docker-vagrant](https://github.com/blinkreaction/boot2docker-vagrant) has a built-in vhost-proxy container that adds support for running multiple projects on the same `IP:port`. The container binds to `192.168.10.10:80` (the default box IP address) and routes web requests based on the Host header. 6 | 7 | See [boot2docker-vagrant docs](https://github.com/blinkreaction/boot2docker-vagrant/blob/develop/docs/networking.md#vhost-proxy) for more information and configuration instructions. 8 | 9 | 10 | ## Without vhost-proxy (Mac, Windows, Linux) 11 | 12 | Follow the [setup](../README.md#setup) instructions for each project making sure that ports used by containers accross all projects do not collide (e.g. two containers cannot use port 80 at the same time). 13 | 14 | This requires a slight modification of the `docker-compose.yml`. 15 | Edit the `ports` key for each container that does port mapping in `docker-compose.yml`. 16 | You can either map unique ports for each container or use dedicated IPs. 17 | 18 | ## Unique ports 19 | 20 | ```yml 21 | ports: 22 | - "8080:80" 23 | - "8443:443" 24 | ``` 25 | 26 | ## Dedicated IP 27 | 28 | ```yml 29 | ports: 30 | - "192.168.10.11:80:80" 31 | - "192.168.10.11:443:443" 32 | ``` 33 | 34 | For Mac and Windows see [boot2docker-vagrant/vagrant.yml](https://github.com/blinkreaction/boot2docker-vagrant/blob/master/vagrant.yml) for instructions on enabling additional IPs for the Boot2docker VM. 35 | -------------------------------------------------------------------------------- /docs/phpcs.md: -------------------------------------------------------------------------------- 1 | # Using PHP Code Sniffer with DDE 2 | 3 | phpcs and phpcbf are readily available in up-to-date version of cli container. 4 | 5 | ## Using as custom dsh command 6 | 7 | It's recommended to see how to [extend dsh with custom commands](custom-commands.md) first. 8 | 9 | From your project's root folder (where `.drude` folder is): 10 | 11 | 1. Download example `phpcs` command 12 | 13 | ``` 14 | mkdir -p .drude/commands 15 | curl https://raw.githubusercontent.com/blinkreaction/drude/develop/examples/.drude/commands/phpcs -ko .drude/commands/phpcs 16 | chmod +x .drude/commands/phpcs 17 | ``` 18 | 2. Use as `dsh phpcs docroot/sites/all/modules/custom` or any path you want to run sniffer against. See `dsh help phpcs` 19 | 3. Modify `.drude/commands/phpcs` script as you need 20 | 4. In the same way you can create script for `phpcbf` as it uses the same set of parameters 21 | 22 | ## Manual usage 23 | 24 | Instead of installing custom command you can just enter it manually every time. 25 | From your project's root folder run 26 | 27 | ```bash 28 | dsh run phpcs \ 29 | --standard=Drupal -n \ 30 | --extensions="php,module,inc,install,test,profile,theme" \ 31 | --ignore="*.features.*,*.pages*.inc" \ 32 | docroot/sites/all/modules/custom 33 | ``` 34 | 35 | ```bash 36 | dsh run phpcbf \ 37 | --standard=Drupal -n \ 38 | --extensions="php,module,inc,install,test,profile,theme" \ 39 | --ignore="*.features.*,*.pages*.inc" \ 40 | docroot/sites/all/modules/custom 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/public-access.md: -------------------------------------------------------------------------------- 1 | # Public Access 2 | 3 | In certain cases you may need to share or expose you local web server on the internet. 4 | E.g. share access with a teammate or customer to demonstrate the work or discuss the progress. 5 | Working with external web services that expect a callback URL is also generally not possible with a local environment. 6 | 7 | ## Welcome to ngrok! 8 | 9 | ngrok creates a tunnel from the public internet **http://subdomain.ngrok.com** to a port on your local machine. 10 | You can give this URL to anyone to allow them to try out a web site you're developing without doing any deployment. 11 | 12 | ## How to use 13 | 14 | Uncomment the **share** service definition section in [`docker-compose.yml`](../docker-compose.yml) to start using ngrok. 15 | 16 | To get the *.ngrok.com address, check the container's logs: 17 | 18 | docker-compose logs share 19 | 20 | The ngrok web inspection interface is running on port 4040. E.g. `http://192.168.10.10:4040` 21 | -------------------------------------------------------------------------------- /docs/sass.md: -------------------------------------------------------------------------------- 1 | # Sass with compass 2 | Cli container already contains `ruby`, `bundler`. 3 | 4 | **Create Gemfile in theme folder** 5 | 6 | Example: 7 | ```ruby 8 | source "https://rubygems.org" 9 | gem 'sass', '~>3.4.0' 10 | gem 'compass' 11 | gem 'bootstrap-sass', '~>3.2.0' 12 | ``` 13 | 14 | **Every developer runs `bundle install` to pull necessary gem dependencies** 15 | 16 | This command should be run in the folder with Gemfile: 17 | > dsh exec bundle install 18 | 19 | There are two folder (`.bundle`, `.bundler`) and a file (`Gemfile.lock`) will be created. 20 | Please add this directories (`.bundle`/`.bundler`) to `.gitignore` 21 | 22 | **Compile sass** 23 | 24 | Please run in the theme folder: 25 | > dsh exec bundle exec compass compile 26 | 27 | This is very important, do not run `compass compile` directly, run it via `bundle exec` so the proper gem versions are used (defined in the Gemfile). 28 | Also you can run watcher to keep your CSS files up to date as changes are made: 29 | > dsh exec bundle exec compass watch 30 | -------------------------------------------------------------------------------- /docs/settings.md: -------------------------------------------------------------------------------- 1 | # Overriding default PHP/MySQL/etc. settings 2 | 3 | 4 | ## Altering PHP and MySQL configuration 5 | 6 | The following configuration files are mounted inside the respective containers and can be used to override the default settings: 7 | 8 | - `.drude/etc/php5/php.ini` - PHP settings overrides 9 | - `.drude/etc/php5/php-cli.ini` - command line PHP settings overrides 10 | - `.drude/etc/mysql/my.cnf` - MySQL settings overrides 11 | 12 | Copy [examples/.drude](../examples/.drude) into the `/.drude` folder in your project repo and modify as necessary. 13 | 14 | 15 | ## Using different PHP versions 16 | 17 | Switching PHP versions is done via the `blinkreaction/drupal-cli` docker image tags. 18 | 19 | To switch to a different image tag: 20 | 21 | - open the `docker-compose.yml` file 22 | - replace the `cli` service `image` property as necessary (see list of available tags below) 23 | - run `dsh up` 24 | 25 | Available PHP versions: 26 | 27 | - `5.6` (`image: blinkreaction/drupal-cli:stable`) - default 28 | - `7.0` (`image: blinkreaction/drupal-cli:php7`) - experimental 29 | 30 | 31 | ## Using different MySQL versions 32 | 33 | Switching MySQL versions is done via the `blinkreaction/drupal-mysql` docker image tags. 34 | 35 | To switch to a different image tag: 36 | 37 | - open the `docker-compose.yml` file 38 | - replace the `db` service `image` property as necessary (see list of available tags below) 39 | - run `dsh up` 40 | 41 | Available MySQL versions: 42 | 43 | - `5.5` (`image: blinkreaction/drupal-mysql:5.5`) 44 | - `5.6` (`image: blinkreaction/drupal-mysql:5.6`) - default. 45 | - `5.7` (`image: blinkreaction/drupal-mysql:5.7`) 46 | -------------------------------------------------------------------------------- /docs/ssh-agent.md: -------------------------------------------------------------------------------- 1 | # Using ssh-agent service 2 | 3 | ssh-agent service allows adding multiple keys (including ones protected with a passphrase) to a single pool of ssh keys, 4 | which can be shared across multiple projects. 5 | 6 | Required dsh version: `1.20.0+` 7 | 8 | # Setup 9 | 10 | 1. Make sure dsh version is `1.20.0` or higher. 11 | 2. `dsh reset ssh-agent` (only necessary when updating from older versions). 12 | 3. Add the following configuration option to the `cli` service in your projects `docker-compose.yml` file: 13 | 14 | For Compose file format version 1 15 | ```yml 16 | cli: 17 | ... 18 | volumes_from: 19 | - ssh-agent 20 | ... 21 | ``` 22 | 23 | For Compose file format version 2 24 | ```yml 25 | cli: 26 | ... 27 | volumes_from: 28 | - container:ssh-agent 29 | ... 30 | ``` 31 | 4. Reset the cli container `dsh reset cli`. 32 | 5. See `dsh help ssh-agent` for more usage information. 33 | -------------------------------------------------------------------------------- /docs/system-requirements.md: -------------------------------------------------------------------------------- 1 | # System requirements 2 | 3 | ## Hardware 4 | 5 | ### RAM 6 | 7 | **8GB** (16GB if you keep lost of apps running) for a comfortable work experience. 8 | 9 | It is possible to use DDE with less than 8GB of RAM (e.g. 4GB), however not recommended. 10 | 11 | The amount of RAM DDE reserves is configurable via the `vagrant.yml` file (2GB by default). 12 | You can lower it to 1GB if your host computer runs low on memory. 13 | Please understand that this will be the amount of RAM available to the application stack and sites running on it. 14 | 15 | ### CPU 16 | 17 | Your CPU should support hardware **VT-x/AMD-V virtualization** (most modern CPUs) and it should be enabled in BIOS. 18 | 19 | ## Software 20 | 21 | While Docker is supported natively on Linux, Mac and Windows users will need a tiny Linux VM layer to be able to run Docker containers. 22 | 23 | DDE relies on the following components for Docker support on Mac and Windows: 24 | 25 | - [VirtualBox](https://www.virtualbox.org) 5.0+ 26 | - [Vagrant](https://www.vagrantup.com) 1.7.3+ 27 | - [Boot2docker Vagrant Box](https://github.com/blinkreaction/boot2docker-vagrant) v1.3.1+ 28 | 29 | **You do not have to install these components manually as DDE automates this for you.** 30 | Please refer to the [setup instructions](/README.md#setup) for further steps. -------------------------------------------------------------------------------- /docs/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting 2 | 3 | Start with [boot2docker-vagrant troubleshooting](https://github.com/blinkreaction/boot2docker-vagrant/blob/master/docs/troubleshooting.md) 4 | 5 | Most of the issues related to VM startup, file sync, etc. will be covered there. 6 | -------------------------------------------------------------------------------- /docs/varnish.md: -------------------------------------------------------------------------------- 1 | # Enabling Varnish support 2 | 3 | ## Setup 4 | 5 | 1. Comment out `VIRTUAL_HOST=.drude` in the `web` service definition in `docker-compose.yml`. 6 | 7 | 2. Add `varnish` service in `docker-compose.yml` 8 | 9 | Replace `` with your project name. 10 | 11 | ``` 12 | # Varnish node 13 | varnish: 14 | hostname: varnish 15 | image: blinkreaction/drupal-varnish:3.0-stable 16 | links: 17 | - web 18 | environment: 19 | - VARNISH_BACKEND_HOST=web..docker 20 | - VIRTUAL_HOST=.drude 21 | ``` 22 | 23 | 3. Apply new configuration with `dsh up` 24 | 25 | 26 | See https://github.com/blinkreaction/docker-drupal-varnish for additional configuration options. 27 | -------------------------------------------------------------------------------- /docs/xdebug.md: -------------------------------------------------------------------------------- 1 | # Debugging with DDE, Xdebug and PhpStorm 2 | 3 | `xdebug` extension is disabled by default as it causes about 20% performance hit. 4 | 5 | There two variants: you can use xdebug for debuging requests from browser or you can debug requests from console (for example Drush commands). 6 | 7 | For configuration first variant use **Prerequisites** and **Setup**. 8 | 9 | For configuration second variant use **Setup for console php**. 10 | 11 | ## Prerequisites 12 | 13 | - [PHPStorm](https://www.jetbrains.com/phpstorm/) 14 | - [Xdebug Helper](https://chrome.google.com/extensions/detail/eadndfjplgieldjbigjakmdgkmoaaaoc) extension for Chrome 15 | 16 | You can also pick from the [list](https://confluence.jetbrains.com/display/PhpStorm/Browser+Debugging+Extensions) of options for other browsers 17 | 18 | ## Setup 19 | 20 | 1. Set environment variable on the `cli` service 21 | 22 | ```yml 23 | cli: 24 | ... 25 | environment: 26 | - XDEBUG_ENABLED=1 27 | ... 28 | ``` 29 | 2. Update container configuration with `dsh up` 30 | 3. Open your project in PHPStorm 31 | 4. Set a breakpoint wherever you like 32 | 5. Click on the **Start Listening for PHP Debug Connections** button in PHPStorm 33 | 34 | 35 | 36 | 6. Click on **Debug** in **Xdebug Helper** in Chrome 37 | 38 | 39 | 40 | 7. Click on **Accept** in the **Incoming Connection From Xdebug** dialogue in PHPStorm 41 | 42 | 43 | 44 | Happy debugging! 45 | 46 | ## Setup for console php 47 | 1. Set environment variable on the `cli` service 48 | 49 | ```yml 50 | cli: 51 | ... 52 | environment: 53 | - XDEBUG_ENABLED=1 54 | - XDEBUG_CONFIG=idekey=PHPSTORM remote_host=192.168.10.1 55 | - PHP_IDE_CONFIG=serverName=drupal7.drude 56 | ... 57 | ``` 58 | You need to replace **drupal7.drude** with your domain. You can find it in `web` section: 59 | ```yml 60 | web: 61 | ... 62 | environment: 63 | - VIRTUAL_HOST=drupal7.drude 64 | ... 65 | ... 66 | ``` 67 | 68 | 2. Update container configuration with `dsh up` 69 | 3. You can run your scripts from console and debug it in the same way as requests from browser. 70 | 71 | For example you can run drush command: 72 | 73 | ```bash 74 | dsh drush fra -y 75 | ``` 76 | 77 | and debug this drush command from feature module. 78 | 79 | ### Resources 80 | 81 | - [Zero-configuration Web Application Debugging with Xdebug and PhpStorm](https://confluence.jetbrains.com/display/PhpStorm/Zero-configuration+Web+Application+Debugging+with+Xdebug+and+PhpStorm) 82 | -------------------------------------------------------------------------------- /examples/.drude/commands/init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | ## Sample init script 5 | 6 | # Set to the appropriate site directory 7 | SITE_DIRECTORY='project' 8 | # Set to the appropriate site directory 9 | SITE_DOMAIN='project.drude' 10 | # Set to the appropriate site alias for the DB source 11 | SOURCE_ALIAS='@project.prod' 12 | 13 | # Console colors 14 | red='\033[0;31m' 15 | green='\033[0;32m' 16 | yellow='\033[1;33m' 17 | NC='\033[0m' 18 | 19 | # Get project root directory 20 | GIT_ROOT=$(git rev-parse --show-toplevel) 21 | if [[ -z $GIT_ROOT ]]; then exit -1; fi 22 | 23 | # Set repo root as working directory. 24 | cd $GIT_ROOT 25 | 26 | # Yes/no confirmation dialog with an optional message 27 | # @param $1 confirmation message 28 | _confirm () 29 | { 30 | while true; do 31 | read -p "$1 Continue? [y/n]: " answer 32 | case $answer in 33 | [Yy]|[Yy][Ee][Ss] ) 34 | echo "Working..." 35 | break 36 | ;; 37 | [Nn]|[Nn][Oo] ) 38 | echo 'Ok, whatever.' 39 | exit 40 | ;; 41 | * ) 42 | echo 'Please answer yes or no.' 43 | esac 44 | done 45 | } 46 | 47 | # Copy a settings file from $source to $dest 48 | # Skips if the $dest already exists. 49 | _copy_settings_file() 50 | { 51 | local source=${1} 52 | local dest=${2} 53 | 54 | if [[ ! -f $dest ]]; then 55 | echo -e "${green}Copying ${dest}...${NC}" 56 | cp $source $dest 57 | else 58 | echo -e "${yellow}${dest} already in place${NC}" 59 | fi 60 | } 61 | 62 | # Copy settings files 63 | init_settings () 64 | { 65 | cd $GIT_ROOT 66 | 67 | _copy_settings_file 'docker-compose.yml.dist' 'docker-compose.yml' 68 | _copy_settings_file "docroot/sites/${SITE_DIRECTORY}/example.settings.local.php" "docroot/sites/${SITE_DIRECTORY}/settings.local.php" 69 | } 70 | 71 | # Import database from the source site alias 72 | db_import () 73 | { 74 | _confirm "Do you want to import DB from ${SOURCE_ALIAS}?" 75 | 76 | cd $GIT_ROOT 77 | cd docroot 78 | dsh drush -l ${SITE_DOMAIN} sql-sync ${SOURCE_ALIAS} @self -y 79 | } 80 | 81 | # Local adjustments 82 | local_settings () 83 | { 84 | cd $GIT_ROOT 85 | echo -e "${yellow}Applying local settings${NC}" 86 | cd docroot 87 | set -x 88 | 89 | dsh drush -l ${SITE_DOMAIN} en stage_file_proxy -y 90 | 91 | set +x 92 | } 93 | 94 | init_settings 95 | dsh reset 96 | db_import 97 | local_settings 98 | 99 | echo -e "${green}All done!${NC}" 100 | echo -e "${green}Add ${SITE_DOMAIN} to your hosts file (/etc/hosts), e.g.:${NC}" 101 | echo -e "192.168.10.10 ${SITE_DOMAIN}" 102 | echo -e "${green}Open http://${SITE_DOMAIN} in your browser to verify the setup.${NC}" 103 | -------------------------------------------------------------------------------- /examples/.drude/commands/phpcs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Run Code Sniffer (phpcs) against given path 4 | ## 5 | ## Usage: dsh phpcs 6 | ## 7 | ## Uses Drupal standards. 8 | ## 9 | ## Includes extensions: php, module, inc, install, test, profile, theme 10 | ## Ignores: features.*, *.pages*.inc 11 | 12 | # Environment variables passed from dsh: 13 | # 14 | # $DRUDE_PATH - (string) absolute path to NEAREST .drude folder 15 | # $YML_PATH - (string) absolute path to NEAREST docker-compose.yml, can be empty 16 | # $DOCKER_RUNNING - (string) "true" or "false" 17 | 18 | if [[ "$1" == "" ]]; then 19 | echo "Usage: dsh phpcs " 20 | exit 1 21 | fi 22 | 23 | dsh run phpcs \ 24 | --standard=Drupal -n \ 25 | --extensions="php,module,inc,install,test,profile,theme" \ 26 | --ignore="*.features.*,*.pages*.inc" \ 27 | "$1" 28 | -------------------------------------------------------------------------------- /examples/.drude/etc/mysql/my.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | ############################### 3 | # Acquia DD settings 4 | #set innodb as default 5 | default-storage-engine=InnoDB 6 | 7 | innodb_log_buffer_size=32M 8 | innodb_buffer_pool_size=256M 9 | innodb_log_file_size=32M 10 | 11 | innodb_file_per_table=1 12 | 13 | #Max packets 14 | max_allowed_packet = 128M 15 | 16 | #Enable slow query log 17 | long_query_time=1 18 | slow_query_log=1 19 | slow_query_log_file=slow.log 20 | ############################### 21 | -------------------------------------------------------------------------------- /examples/.drude/etc/php5/php-cli.ini: -------------------------------------------------------------------------------- 1 | ; PHP CLI settings 2 | [php] 3 | ; Maximum amount of memory a script may consume 4 | memory_limit = 512M 5 | 6 | ; Error reporting 7 | display_errors = On 8 | display_startup_errors = On 9 | error_reporting = E_ALL | E_STRICT 10 | html_errors = Off 11 | log_errors = On 12 | -------------------------------------------------------------------------------- /examples/.drude/etc/php5/php.ini: -------------------------------------------------------------------------------- 1 | ; PHP settings 2 | [php] 3 | ; Maximum amount of memory a script may consume 4 | memory_limit = 256M 5 | 6 | ; https://php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data 7 | always_populate_raw_post_data = -1 8 | 9 | ; Error reporting 10 | display_errors = On 11 | display_startup_errors = On 12 | error_reporting = E_ALL | E_STRICT 13 | html_errors = On 14 | log_errors = On 15 | 16 | ; APC opcode cache settings (PHP 5.3) 17 | [apc] 18 | apc.enabled=1 19 | apc.shm_segments=1 20 | apc.shm_size=128M 21 | apc.ttl=7200 22 | apc.user_ttl=7200 23 | apc.num_files_hint=1024 24 | apc.enable_cli=0 25 | 26 | ; OPcache settigns (PHP 5.5) 27 | [opcache] 28 | opcache.memory_consumption=128 29 | 30 | ; Xdebug settings 31 | [xdebug] 32 | ;xdebug.remote_enable=1 33 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Bats tests for dsh 2 | 3 | You need to install [Bats](https://github.com/sstephenson/bats) before running tests. 4 | You need to have [Drupal 7 sample project](https://github.com/blinkreaction/drude-d7-testing) installed in your projects directory. 5 | You must have next structure of projects directory: 6 | > projects 7 | > ... 8 | > \_ drude 9 | > \_ drude-d7-testing 10 | > ... 11 | 12 | You need to install additional bats sub-modules. To perform this, perform next actions. 13 | ``` 14 | cd ~/projects/drude/tests 15 | git submodule init 16 | git submodule update 17 | ``` 18 | 19 | You can run any test from **drude-d7-testing** directory using next command: 20 | ``` 21 | bats ../drude/tests/start.bats 22 | ``` 23 | 24 | By default OS is "OS X" (mac). You can set enviroment for test (OS is mac|linux|win): 25 | ``` 26 | OS=linux bats ../drude/tests/start.bats 27 | ``` 28 | 29 | You can run all tests using next command (it must be run from **drude/tests directory**): 30 | ``` 31 | ./run-tests.sh 32 | ``` 33 | 34 | Or you can set OS: 35 | ``` 36 | OS=linux ./run-tests.sh 37 | ``` 38 | or specify parameter: 39 | 40 | ``` 41 | ./run-tests.sh linux 42 | ``` 43 | 44 | 45 | ## Tests overview 46 | 47 | In most cases test name is same as commands name: 48 | ``` 49 | init.bats => dsh init 50 | start.bats => dsh start 51 | ... 52 | ``` 53 | 54 | There are also files with tests for dsh functions: 55 | ``` 56 | helper_functions.bats - Helper functions 57 | basics_check_functions.bats - Basics check functions 58 | control_functions.bats - Control functions 59 | ``` 60 | 61 | ## Troubleshooting test 62 | 63 | Tests directory contains ```troubleshooting.bats```, which should not be started in general and not included in ```run-tests.sh```. 64 | This test have to be performed when something goes wrong. 65 | -------------------------------------------------------------------------------- /tests/basics_check_functions.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking is_linux function." { 6 | # Value from preset variable. 7 | [[ "$OS" = "linux" ]] && linux=0 || linux=1 8 | 9 | run is_linux 10 | 11 | # 12 | echo "===============================================================" 13 | echo "Is linux: $linux" 14 | echo "OS: $OS" 15 | # 16 | 17 | [ $status -eq $linux ] 18 | } 19 | 20 | @test "Checking is_windows function." { 21 | # Value from preset variable. 22 | [[ "$OS" = "win" ]] && win=0 || win=1 23 | 24 | run is_windows 25 | 26 | # 27 | echo "===============================================================" 28 | echo "Is win: $win" 29 | echo "OS: $OS" 30 | # 31 | 32 | [ $status -eq $win ] 33 | } 34 | 35 | @test "Checking is_boot2docker function." { 36 | # Check if boot2docker console (@todo upd this test) 37 | run bash -c 'uname -a|grep "boot2docker"' 38 | boot2socker=$output 39 | is_boot2socker=$([[ ! "$boot2docker" = '' ]] && echo 0 || echo 1) 40 | 41 | run is_boot2docker 42 | 43 | # 44 | echo "===============================================================" 45 | echo "Is boot2docker: $is_boot2socker" 46 | # 47 | 48 | [ $status -eq $is_boot2socker ] 49 | } 50 | 51 | @test "Checking is_mac function." { 52 | # Value from preset variable. 53 | [[ "$OS" = "mac" ]] && mac=0 || mac=1 54 | 55 | run is_mac 56 | 57 | # 58 | echo "===============================================================" 59 | echo "Is mac: $mac" 60 | echo "OS: $OS" 61 | # 62 | 63 | [ $status -eq $mac ] 64 | } 65 | 66 | @test "Checking is_docker_beta function. Case#1 Not beta version" { 67 | DOCKER_BETA=0 68 | run is_docker_beta 69 | 70 | [ $status -eq 1 ] 71 | } 72 | 73 | @test "Checking is_docker_beta function. Case#2 Beta version" { 74 | DOCKER_BETA=1 75 | run is_docker_beta 76 | 77 | [ $status -eq 0 ] 78 | } 79 | 80 | @test "Checking is_binary_found function. Case#1: existing binary" { 81 | run is_binary_found 'docker' 82 | 83 | [ $status -eq 0 ] 84 | } 85 | 86 | @test "Checking is_binary_found function. Case#2: fake binary" { 87 | run is_binary_found 'fake_binary' 88 | 89 | [ $status -eq 1 ] 90 | } 91 | 92 | @test "Checking check_binary_found function. Case#1: existing binary" { 93 | run check_binary_found 'docker' 94 | 95 | [ $status -eq 0 ] 96 | } 97 | 98 | @test "Checking check_binary_found function. Case#2: fake binary" { 99 | run check_binary_found 'fake_binary' 100 | 101 | [ $status -eq 1 ] 102 | } -------------------------------------------------------------------------------- /tests/control_functions.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking check_yml function. Case#1 Linux docker-compose exists." { 6 | if [[ "$OS" = "linux" || $(is_docker_beta) -ne 0 ]]; then 7 | run check_yml 8 | 9 | [ $status -eq 0 ] 10 | fi 11 | } 12 | 13 | @test "Checking check_yml function. Case#1 Linux docker-compose not exists." { 14 | if [[ "$OS" = "linux" ]]; then 15 | cd .. 16 | run check_yml 17 | 18 | [ $status -eq 1 ] 19 | fi 20 | } 21 | 22 | @test "Checking check_yml function. Case#1 Win and Mac docker-compose and vagrant exists." { 23 | if [[ "$OS" != "linux" ]]; then 24 | run check_yml 25 | 26 | [ $status -eq 0 ] 27 | fi 28 | } 29 | 30 | @test "Checking check_yml function. Case#1 Win and Mac docker-compose and vagrant not exists." { 31 | if [[ "$OS" != "linux" ]]; then 32 | cd .. 33 | run check_yml 34 | 35 | [ $status -eq 1 ] 36 | fi 37 | } 38 | 39 | @test "Checking check_drush_path function. Case#1 - inside docroot." { 40 | cd docroot/sites 41 | run check_drush_path 42 | 43 | [ $status -eq 0 ] 44 | } 45 | 46 | @test "Checking check_drush_path function. Case#2 - outside docroot." { 47 | run check_drush_path 48 | 49 | [ $status -eq 1 ] 50 | [[ $output =~ "dsh: This command must be run inside Drupal's document root" ]] 51 | } -------------------------------------------------------------------------------- /tests/drush.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh drush --version" { 6 | dsh drush --version 7 | } 8 | 9 | @test "Checking output of dsh drush --version" { 10 | run dsh drush --version 11 | 12 | [ $status -eq 0 ] 13 | [[ ${lines[0]} =~ "Drush Version : 8.1.3" ]] 14 | } 15 | 16 | @test "Checking output of dsh drush st (Drupal version)" { 17 | cd ./docroot 18 | run dsh drush st 19 | 20 | [ $status -eq 0 ] 21 | [[ ${lines[0]} =~ "Drupal version : 7.34" ]] 22 | 23 | cd .. 24 | } -------------------------------------------------------------------------------- /tests/dsh_script.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | # Include dsh script for usign internal dsh function. 4 | setup() { 5 | . /usr/local/bin/dsh > /dev/null 6 | 7 | # If you check your update in dsh. 8 | #. ../drude/bin/dsh > /dev/null 9 | 10 | # Current system variables. 11 | OS="${OS:-mac}" 12 | } 13 | 14 | teardown() { 15 | echo "+==============================================================" 16 | echo "< Current output >:" 17 | echo $output 18 | echo "< Current lines >:" 19 | for line in "${lines[@]}"; do 20 | echo $line 21 | done 22 | echo "+==============================================================" 23 | } -------------------------------------------------------------------------------- /tests/exec.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh exec pwd" { 6 | dsh exec pwd 7 | } 8 | 9 | @test "Checking output of dsh exec pwd" { 10 | run dsh exec pwd 11 | 12 | [ $status -eq 0 ] 13 | [[ $output =~ "/var/www" ]] 14 | } 15 | 16 | @test "Checking output of dsh exec uname -r" { 17 | run dsh exec uname -r 18 | 19 | [ $status -eq 0 ] 20 | [[ $output =~ "3.19.0-56-generic" ]] 21 | } 22 | 23 | @test "Checking dsh _run function - pwd test" { 24 | run _run pwd 25 | 26 | [ $status -eq 0 ] 27 | [[ $output =~ "/var/www" ]] 28 | } 29 | 30 | @test "Checking dsh _run function - uname test" { 31 | run _run uname -r 32 | 33 | [ $status -eq 0 ] 34 | [[ $output =~ "3.19.0-56-generic" ]] 35 | } -------------------------------------------------------------------------------- /tests/helper_functions.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | true_if_failed() { 6 | true 7 | if_failed 8 | } 9 | 10 | @test "Checking if_failed function. Text #1" { 11 | run true_if_failed 12 | 13 | [ $status -eq 0 ] 14 | } 15 | 16 | not_true_if_failed() { 17 | ! true 18 | if_failed 19 | } 20 | 21 | @test "Checking if_failed function. Text #2" { 22 | run not_true_if_failed 23 | 24 | [ $status -eq 1 ] 25 | } 26 | 27 | @test "Checking upfind function. Text #1" { 28 | run upfind $(pwd)/docroot/sites 29 | 30 | [ $status -eq 0 ] 31 | [ $output = $(pwd) ] 32 | } 33 | 34 | @test "Checking upfind function. Text #2" { 35 | run upfind $(pwd)/dir_not_exists 36 | 37 | [ $status -eq 0 ] 38 | [ "$output" = "" ] 39 | } 40 | 41 | @test "Checking upfind function. Text #3" { 42 | run upfind "" 43 | 44 | [ $status -eq 1 ] 45 | } 46 | 47 | @test "Checking get_yml_path function" { 48 | run get_yml_path 49 | echo $output 50 | 51 | [ $status -eq 0 ] 52 | [ $output = "$(pwd)" ] 53 | } 54 | 55 | @test "Checking get_drude_path function" { 56 | run get_drude_path 57 | 58 | [ $status -eq 0 ] 59 | [ $output = $(pwd) ] 60 | } 61 | 62 | @test "Checking get_abs_path function" { 63 | run get_abs_path ./docroot/sites 64 | 65 | [ $status -eq 0 ] 66 | [ "$output" = "$(pwd)/docroot/sites" ] 67 | } 68 | 69 | @test "Checking get_current_relative_path function. Case#1: Inside docroot folder condition" { 70 | cd docroot/sites/all 71 | run get_current_relative_path 72 | 73 | # 74 | echo "+==============================================================" 75 | local proj_root=$(get_yml_path) 76 | echo "+ Project root: $proj_root" 77 | local cwd=$(pwd) 78 | echo "+ Current directory: $cwd" 79 | local pathdiff=${cwd#$proj_root/} 80 | echo "+ Path diff: $pathdiff" 81 | # 82 | 83 | [ $status -eq 0 ] 84 | [ "$output" = "docroot/sites/all" ] 85 | } 86 | 87 | # @todo check this function 88 | @test "Checking get_current_relative_path function. Case#2: Outside docroot folder condition" { 89 | run get_current_relative_path 90 | 91 | # 92 | echo "+==============================================================" 93 | local proj_root=$(get_yml_path) 94 | echo "+ Project root: $proj_root" 95 | local cwd=$(pwd) 96 | echo "+ Current directory: $cwd" 97 | local pathdiff=${cwd#$proj_root/} 98 | echo "+ Path diff: $pathdiff" 99 | # 100 | 101 | [ $status -eq 0 ] 102 | [ "$output" = "$cwd" ] 103 | } 104 | 105 | @test "Checking clean_string function." { 106 | local string="Abc-123/" 107 | run clean_string $string 108 | 109 | # 110 | local cleaned=$(echo "$string" | sed -e 's/[^a-zA-Z0-9_-]$//') 111 | echo ${cleaned} 112 | echo "+==============================================================" 113 | echo "+ Input string: $string" 114 | # 115 | 116 | [ $status -eq 0 ] 117 | [ "$output" = "Abc-123" ] 118 | } 119 | 120 | @test "Checking get_mysql_connect function. Case#1: Outside of docroot" { 121 | run get_mysql_connect 122 | 123 | # 124 | echo "===============================================================" 125 | echo "Output of sql-connect with disabled TTY: $(DRUDE_IS_TTY=0 _run drush sql-connect)" 126 | # 127 | 128 | [ $status -eq 0 ] 129 | [ "${lines[8]}" = "#1 [internal function]: drush_sql_connect()" ] 130 | } 131 | 132 | @test "Checking get_mysql_connect function. Case#2: Inside of docroot" { 133 | cd docroot/sites 134 | run get_mysql_connect 135 | 136 | # 137 | echo "===============================================================" 138 | echo "Output of sql-connect with disabled TTY: $(DRUDE_IS_TTY=0 _run drush sql-connect)" 139 | echo "===============================================================" 140 | # 141 | 142 | [ $status -eq 0 ] 143 | [[ "$output" =~ "mysql --user=drupal --password=123 --database=drupal --host" ]] 144 | } 145 | 146 | @test "Checking docker_compose function. Case#1: Call without specified command" { 147 | run docker_compose 148 | 149 | # 150 | cwd=$(pwd) 151 | echo "+==============================================================" 152 | echo "+ Current path: $cwd" 153 | cd $(get_yml_path) 154 | echo "+ Yml path directory: $(pwd)" 155 | # 156 | 157 | [ $status -eq 1 ] 158 | [ "${lines[0]}" = "Define and run multi-container applications with Docker." ] 159 | } 160 | 161 | @test "Checking docker_compose function. Case#2: Call with specified command" { 162 | run docker_compose version 163 | 164 | # 165 | cwd=$(pwd) 166 | echo "+==============================================================" 167 | echo "+ Current path: $cwd" 168 | cd $(get_yml_path) 169 | echo "+ Yml path directory: $(pwd)" 170 | # 171 | 172 | [ $status -eq 0 ] 173 | } 174 | 175 | @test "Checking get_container_id function. Case#1: cli" { 176 | run get_container_id 'cli' 177 | 178 | # 179 | echo "===============================================================" 180 | echo "Docker compose output: " 181 | compose_output=$(docker-compose ps -q cli | tr -d '\r') 182 | echo $compose_output 183 | # 184 | 185 | [ $status -eq 0 ] 186 | [ "$output" = $compose_output ] 187 | } 188 | 189 | @test "Checking get_container_id function. Case#2: web" { 190 | run get_container_id 'web' 191 | 192 | # 193 | echo "===============================================================" 194 | echo "Docker compose output: " 195 | compose_output=$(docker-compose ps -q web | tr -d '\r') 196 | echo $compose_output 197 | # 198 | 199 | [ $status -eq 0 ] 200 | [ "$output" = $compose_output ] 201 | } -------------------------------------------------------------------------------- /tests/helpers/helper.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | # Some helper functions were took here: https://github.com/gaia-adm/docker-bench-test 4 | 5 | # Returns the absolute path of a given string 6 | abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; } 7 | 8 | # Compares versions of software of the format X.Y.Z 9 | do_version_check() { 10 | [ "$1" = "$2" ] && return 10 11 | 12 | ver1front=$(printf "%s" "$1" | cut -d "." -f -1) 13 | ver1back=$(printf "%s" "$1" | cut -d "." -f 2-) 14 | ver2front=$(printf "%s" "$2" | cut -d "." -f -1) 15 | ver2back=$(printf "%s" "$2" | cut -d "." -f 2-) 16 | 17 | if [ "$ver1front" != "$1" ] || [ "$ver2front" != "$2" ]; then 18 | [ "$ver1front" -gt "$ver2front" ] && return 11 19 | [ "$ver1front" -lt "$ver2front" ] && return 9 20 | 21 | [ "$ver1front" = "$1" ] || [ -z "$ver1back" ] && ver1back=0 22 | [ "$ver2front" = "$2" ] || [ -z "$ver2back" ] && ver2back=0 23 | do_version_check "$ver1back" "$ver2back" 24 | return $? 25 | else 26 | [ "$1" -gt "$2" ] && return 11 || return 9 27 | fi 28 | } 29 | 30 | get_etc_path(){ 31 | # running in Docker container: mount /etc directory to /host/etc 32 | if [ -d /host/etc ]; then 33 | echo "/host/etc" 34 | else 35 | echo "/etc" 36 | fi 37 | } 38 | 39 | # Compares two strings and returns 0 if the second is a substring of the first 40 | contains() { 41 | string="$1" 42 | substring="$2" 43 | if [ "${string#*$substring}" != "$string" ] 44 | then 45 | return 0 # $substring is in $string 46 | else 47 | return 1 # $substring is not in $string 48 | fi 49 | } 50 | 51 | # Extracts all commandline args from the oldest running processes named like the first parameter 52 | get_command_line_args() { 53 | PROC="$1" 54 | 55 | for PID in $(pgrep -x -o "$PROC") 56 | do 57 | tr "\0" " " < /proc/"$PID"/cmdline 58 | done 59 | } 60 | 61 | # Extract the cumulative command line arguments for the docker daemon 62 | # 63 | # If specified multiple times, all matches are returned. 64 | # Accounts for long and short variants, call with short option. 65 | # Does not account for option defaults or implicit options. 66 | get_docker_cumulative_command_line_args() { 67 | OPTION="$1" 68 | 69 | get_command_line_args docker | 70 | # normalize known long options to their short versions 71 | sed \ 72 | -e 's/\-\-debug/-D/g' \ 73 | -e 's/\-\-host/-H/g' \ 74 | -e 's/\-\-log-level/-l/g' \ 75 | -e 's/\-\-version/-v/g' \ 76 | | 77 | # normalize parameters separated by space(s) to -O=VALUE 78 | sed \ 79 | -e 's/\-\([DHlv]\)[= ]\([^- ][^ ]\)/-\1=\2/g' \ 80 | | 81 | # get the last interesting option 82 | tr ' ' "\n" | 83 | grep "^${OPTION}" | 84 | # normalize quoting of values 85 | sed \ 86 | -e 's/"//g' \ 87 | -e "s/'//g" 88 | } 89 | 90 | # Extract the effective command line arguments for the docker daemon 91 | # 92 | # Accounts for multiple specifications, takes the last option. 93 | # Accounts for long and short variants, call with short option 94 | # Does not account for option default or implicit options. 95 | get_docker_effective_command_line_args() { 96 | OPTION="$1" 97 | get_docker_cumulative_command_line_args $OPTION | tail -n1 98 | } 99 | 100 | get_systemd_service_file(){ 101 | SERVICE="$1" 102 | 103 | if [ -f "$(get_etc_path)/systemd/system/$SERVICE" ]; then 104 | echo "$(get_etc_path)/systemd/system/$SERVICE" 105 | elif systemctl show -p FragmentPath "$SERVICE" 2> /dev/null 1>&2; then 106 | systemctl show -p FragmentPath "$SERVICE" | sed 's/.*=//' 107 | else 108 | echo "/usr/lib/systemd/system/$SERVICE" 109 | fi 110 | } -------------------------------------------------------------------------------- /tests/init.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | @test "Checking init drude-d7-testing project" { 4 | dsh init 5 | } -------------------------------------------------------------------------------- /tests/reset.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh reset -f" { 6 | dsh reset -f 7 | } 8 | 9 | @test "Checking output of dsh reset -f" { 10 | run dsh reset -f 11 | 12 | [ $status -eq 0 ] 13 | [[ ${lines[0]} =~ "Removing containers..." ]] 14 | [[ ${lines[1]} =~ "Killing druded7testing" ]] 15 | [[ ${lines[2]} =~ "Killing druded7testing" ]] 16 | [[ ${lines[3]} =~ "Killing druded7testing" ]] 17 | [[ ${lines[4]} =~ "Removing druded7testing" ]] 18 | [[ ${lines[5]} =~ "Removing druded7testing" ]] 19 | [[ ${lines[6]} =~ "Removing druded7testing" ]] 20 | } 21 | 22 | @test "Checking output of dsh reset cli" { 23 | run dsh reset cli 24 | 25 | [ $status -eq 0 ] 26 | [[ ${lines[0]} =~ "Killing druded7testing" ]] 27 | [[ ${lines[1]} =~ "Removing druded7testing" ]] 28 | } 29 | 30 | @test "Checking output of dsh reset db" { 31 | run dsh reset db 32 | 33 | [ $status -eq 0 ] 34 | [[ ${lines[0]} =~ "Killing druded7testing" ]] 35 | [[ ${lines[1]} =~ "Removing druded7testing" ]] 36 | } 37 | 38 | @test "Checking output of dsh reset web" { 39 | run dsh reset web 40 | 41 | [ $status -eq 0 ] 42 | [[ ${lines[0]} =~ "Killing druded7testing" ]] 43 | [[ ${lines[1]} =~ "Removing druded7testing" ]] 44 | } 45 | 46 | @test "Checking dsh remove function" { 47 | run remove -f 48 | 49 | [ $status -eq 0 ] 50 | [[ ${lines[0]} =~ "Removing containers..." ]] 51 | [[ ${lines[1]} =~ "Killing druded7testing" ]] 52 | [[ ${lines[2]} =~ "Killing druded7testing" ]] 53 | [[ ${lines[3]} =~ "Killing druded7testing" ]] 54 | [[ ${lines[4]} =~ "Removing druded7testing" ]] 55 | [[ ${lines[5]} =~ "Removing druded7testing" ]] 56 | [[ ${lines[6]} =~ "Removing druded7testing" ]] 57 | 58 | # Rerun containers after removing. 59 | dsh up > /dev/null 60 | } 61 | 62 | -------------------------------------------------------------------------------- /tests/restart.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh restart" { 6 | dsh restart 7 | } 8 | 9 | @test "Checking output of dsh restart" { 10 | run dsh restart 11 | 12 | [ $status -eq 0 ] 13 | [[ ${lines[0]} =~ "Restarting services..." ]] 14 | [[ ${lines[1]} =~ "Restarting druded7testing" ]] 15 | [[ ${lines[2]} =~ "Restarting druded7testing" ]] 16 | [[ ${lines[3]} =~ "Restarting druded7testing" ]] 17 | [[ ${lines[4]} =~ "Connecting vhost-proxy to networks..." ]] 18 | [[ ${lines[5]} =~ "Container and host" ]] 19 | } 20 | 21 | @test "Checking dsh _restart_containers function" { 22 | run _restart_containers 23 | 24 | [ $status -eq 0 ] 25 | [[ ${lines[0]} =~ "Restarting services..." ]] 26 | [[ ${lines[1]} =~ "Restarting druded7testing" ]] 27 | [[ ${lines[2]} =~ "Restarting druded7testing" ]] 28 | [[ ${lines[3]} =~ "Restarting druded7testing" ]] 29 | [[ ${lines[4]} =~ "Connecting vhost-proxy to networks..." ]] 30 | [[ ${lines[5]} =~ "Container and host" ]] 31 | } 32 | 33 | -------------------------------------------------------------------------------- /tests/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Switch to drude-d7-testing folder. 4 | cd ../../drude-d7-testing 5 | 6 | OS="${OS:-mac}" 7 | if [ ! -z "$1" ]; then 8 | OS="$1" 9 | fi 10 | 11 | # Run tests. Order is important. 12 | echo "Test command: start" 13 | OS=$OS bats ../drude/tests/start.bats 14 | echo "Test command: init" 15 | OS=$OS bats ../drude/tests/init.bats 16 | echo "Test command: stop" 17 | OS=$OS bats ../drude/tests/stop.bats 18 | echo "Test command: reset" 19 | OS=$OS bats ../drude/tests/reset.bats 20 | echo "Test command: restart" 21 | OS=$OS bats ../drude/tests/restart.bats 22 | echo "Test command: drush" 23 | OS=$OS bats ../drude/tests/drush.bats 24 | echo "Test command: exec" 25 | OS=$OS bats ../drude/tests/exec.bats 26 | echo "Test command: ssh-add" 27 | OS=$OS bats ../drude/tests/ssh-add.bats 28 | echo "Test command: status" 29 | OS=$OS bats ../drude/tests/status.bats 30 | echo "Test command: update" 31 | OS=$OS bats ../drude/tests/update.bats 32 | echo "Test dsh helper functions" 33 | OS=$OS bats ../drude/tests/helper_functions.bats 34 | echo "Tests dsh basics check functions" 35 | OS=$OS bats ../drude/tests/basics_check_functions.bats 36 | echo "Tests dsh control functions" 37 | OS=$OS bats ../drude/tests/control_functions.bats -------------------------------------------------------------------------------- /tests/ssh-add.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh ssh-add -D" { 6 | dsh ssh-add -D 7 | } 8 | 9 | @test "Checking dsh ssh-add -l" { 10 | run dsh ssh-add -l 11 | 12 | [ $status -eq 1 ] 13 | } 14 | 15 | @test "Checking dsh ssh-add bats_rsa" { 16 | cp ../drude/tests/ssh-key/* ~/.ssh 17 | dsh ssh-add bats_rsa 18 | } 19 | 20 | @test "Checking dsh ssh-add: key doesn't exist" { 21 | run dsh ssh-add doesnt_exist_rsa 22 | 23 | [ $status -eq 1 ] 24 | [[ $output =~ "/.ssh/doesnt_exist_rsa: No such file or directory" ]] 25 | } 26 | 27 | @test "Checking dsh ssh-add -l (one key)" { 28 | run dsh ssh-add -l 29 | 30 | [ $status -eq 0 ] 31 | [[ $output =~ "4096 SHA256" ]] 32 | } 33 | 34 | @test "Checking dsh ssh-add -D" { 35 | run dsh ssh-add -D 36 | 37 | [ $status -eq 0 ] 38 | [[ $output =~ "All identities removed." ]] 39 | } 40 | 41 | @test "Checking dsh ssh-add -l (no keys)" { 42 | run dsh ssh-add -l 43 | 44 | [ $status -eq 1 ] 45 | [[ $output =~ "The agent has no identities." ]] 46 | } 47 | 48 | @test "Checking dsh ssh_add function" { 49 | run ssh_add bats_rsa 50 | 51 | [ $status -eq 0 ] 52 | } -------------------------------------------------------------------------------- /tests/ssh-key/bats_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIJKQIBAAKCAgEAupYvJul+AnJDeMOZqA13KD9yrhCwmjioqKkFchnmw6BrB4da 3 | 1NDjsZWGrLVaUb3o2ou1RJkdZptoajQv4CppdYgF6QmwXUv4QPnIArNiLYK9XCm3 4 | /Mb8MiYy25r0QvWaIuHrOvaE3cprjFwq+73P2Is9T85Jllb+hIUnTEcPZMgCtOHy 5 | wrz/qAfyS3zD6WuM4q9K9VgtKYK+iaXfjn+ku8X3VvFGRY0kCkt1S3KE5bQ7m8YM 6 | b8nHxoKSCEJy5fZRaNwSZHL9BMWefg7LH6S3GMuNWxdBMHN22uE6/Zqo/KIL0a5q 7 | ONxyUjHLagU7p3X6dVZ3nQANzj6lHLt6jgEaR1Ic4PEs5UHAWss8RpyhIE3KsRQ6 8 | OBb9DUJlpnUTdGJR73iug13QvcUUHlLBVGtGI27UksUOBSGHW0ZHUYJH9EmvjpE4 9 | lO44y8kXJJyJQFUoJ7BIi9TVBg2x1/7MdjpvpIzeurj0qO4h49dplf9qfko1EYOy 10 | 4tf5H9K+ey93E1iBXFtkNqHimRSV7/7u+AybVz99QM9mv17c15GOPqkuiTvuZZH1 11 | hPQHaGsehJ89fUMOLNf5itayiF4GW5pUnpF+gEIzKmzB2FhBErKlcTFpx13SColS 12 | 8Z0aU3WHJ0nnb8OsHtC1OogT7EDLEVOS2xukvMCsLR9ZRYdRVD9lOK60qecCAwEA 13 | AQKCAgBombEtW1BtBqmUlfMaJxJZ2dfshSa8Dm9evgJziNm5acEWo2bkT4aWE4FA 14 | aRqNIK3ddtzT7BJzZ0QN5dvBC4W7gdnuXqQkaWZu5pieCvpLETQe6rReXR8c7hUs 15 | z52HvDAAxi4dC/5IaCYKtdDS+AIBH23rw3W1dmeQ2yTAukWC9i2uQczaJyIbjPjk 16 | ILmjrct5eVPIXvpSfx1aBUdil2Q+cCjM8M24R/ugWdUTyst+CqAwH8LxGGmKe8Bq 17 | KPZIvOG+q0EUVvJJLpA/kwOEZc7Pc613F35QLyq+Ye20JnP9zMpbbi/WWJ8uPQQQ 18 | F4btxlH2XdcIiPM0YCIoDWITIcMcqv08UvPcELH0xgSOmiIW3DIEMT+jnb+JY1e4 19 | inKIjNvTt/YtccEZoECF2Coo2QKIXiXpStfsBEpS0BqCS8w9kAb3127QlsfqNqwi 20 | NmAhu+z9oZyH9/ScBWxSEO78f4ynLl0ivG0ArqBkEfOmZMd7F+/jk6onCu/9jV4T 21 | lxO0RLeYVGR6kNoKIpQv9PX9wNbTX0Hq052yNWyONE9rqmXiQ705RSh5AB0LXiHd 22 | vfHz9vrQy+4vANHnl3kjn96S9M2i4Xz1eVPxt+P3dNYKcr4qks1jP4VNVTYe7Fi9 23 | OM60CL8fL0xuXkzyKOyDjXdfWGjbBTB/oeGz+z1DroeTJf0kIQKCAQEA6OIcZEEh 24 | 4D6ylhUAFMFJsCpF87IR3zkcc6yDz1/vWKk7/uv0+2cQ/bLKoIwoOCR2mbe6EfC6 25 | UIMBJuyTa6Ui24bKbFBrr0aOQ1wxpMvi1msFw0o4wW7Fs0TKgy54t0BN3GZsTDyU 26 | gLSSCzlheXCof4tLnybKHoIpP4Tpk3Fsnk75mlwxLKfM+Nm2cL4D+qytmlrmcbKk 27 | PCJqOSYE/1A6sWj3UEXEIuefxF4tehxZ+CCaTAecmb/vqz3odcEwRKUtAXtUpr6s 28 | +YEZnqssOD2KdC/RFFrHnHsjUn0UNocx189tW+jFjXcpYXCrMVlEHofH1VUm9rsK 29 | wP8nCQqeuqjKawKCAQEAzRucuILACE2xvWh2c3e0ESXkfB5tMmuCo6BGVelYuep5 30 | Tyi5MhDaSJsBozZ5vn5Wnv+Hj3VRiDNEHWwP2PBKnSWeHFTxjCWZwlWhQkB43VDX 31 | PWNDoa33CXTxoWdTAS8f33WKFjUo1P16628qH9BOs9DL6ocPkzQt+WeM1dxEQRiR 32 | xfyhDi81tZHl7s7pCoOwtbyUWyK+RhsWk0KuthfbXVhT2Hy7tlpt2ga+qUU+/ZCt 33 | nmAO91iaePjstiIyb71tkdNLtbm8DWi2NWm7j6y+kHHvyT/ClN/SOHJxRUtcOLWz 34 | jr/uVyaOCvs24K25jQpQi/BlNjzqxt6oGW2ugvg1dQKCAQEAsDAQ5tBX/r2wgtdU 35 | fl9VjpAM6Df6SXV9zw3fkw6zl9JBb7W4XFM3iZiwsBIZg5Aiol1byqLjcnIKdxZY 36 | 2gHPg2JQ1u1o6uxoSRIBBPqznSDO9Va75awWqnAK/oA0F//waCSdHnheqZjzPMam 37 | tifDcutBxSClnbs/1ayKwl/3mzWIpX3GPlCdRFACNP2tKQNnO/Y1jiNnGY+36ZCY 38 | C0j5fqs5IGQH5ZhzSS8vHMlCT/Tqh0bi9Xc+rcFik2QbTnPgvtQ90QFFAGbpqR87 39 | jzkP/KMIfWvIxNxsdsXmevKBhRKLXBOZElPq3KtO+UDdxnNXflCz78rGcgkX0UFV 40 | oUZ+DQKCAQAY0XCDOv71gkExhARhMGjPcmBVTHE2GqAyIGCiYJvl0yNemrTeBAAF 41 | rQvjreHJVQwyLQVALJfy/REO5lZ8j4bXwQeCshyQMrSKOUZL9/UoAnIo8WvrkltD 42 | /6yFNTVr/UHEDjrpOQF51DodZtQYCWKci3VBKZqO20980DTQY9i2b7yj0k/CoZ/E 43 | GqVR4iN8rDajpu/kny2a2gg/RWBSlExs3RU4Ks+j3wlPymUjokde8zSu5zyoXUZD 44 | wQsTdsvXjXpGnOSaVqEUlkkF6YdSeTqNy9uR5G8tCHAteFuQYPAFxKa3bS3vybCC 45 | T6dyRFMhZ9AbPrlgeLqH2cVJXmYxXstJAoIBAQCVrLgNua2Kb9PDOP8Q9L+Rnegv 46 | EaU9WHF6y3/QUYyTItT3WgejikfvdOjIUbF6VsHjWqSLQ96Wep7TYwx/qCvECaaG 47 | gdwZPND5Ldw/0C2fwEMEirHAnESbogyY7Fl11NFWViSV/2m61ME0Eu4dx4ly0IUb 48 | WeGe+zwnfgCkk8xiRoKaHZp9s3a0n29Rr6cDnjRWYFHz38LU3vSkK2FyKv8Dc8+N 49 | Xdtd6H5UbHy0JyjqiotoLRvA+VkiGL+bVGiUt2xmoqxiiQz7+JkHlQ1mSm2P6NO4 50 | Fkl29LmNisOblnMbxgGsoTGiQWFE2JZcUVogcUSw+Hu+re23t5ohJTKq0AiT 51 | -----END RSA PRIVATE KEY----- 52 | -------------------------------------------------------------------------------- /tests/ssh-key/bats_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6li8m6X4CckN4w5moDXcoP3KuELCaOKioqQVyGebDoGsHh1rU0OOxlYastVpRvejai7VEmR1mm2hqNC/gKml1iAXpCbBdS/hA+cgCs2Itgr1cKbf8xvwyJjLbmvRC9Zoi4es69oTdymuMXCr7vc/Yiz1PzkmWVv6EhSdMRw9kyAK04fLCvP+oB/JLfMPpa4zir0r1WC0pgr6Jpd+Of6S7xfdW8UZFjSQKS3VLcoTltDubxgxvycfGgpIIQnLl9lFo3BJkcv0ExZ5+DssfpLcYy41bF0Ewc3ba4Tr9mqj8ogvRrmo43HJSMctqBTundfp1VnedAA3OPqUcu3qOARpHUhzg8SzlQcBayzxGnKEgTcqxFDo4Fv0NQmWmdRN0YlHveK6DXdC9xRQeUsFUa0YjbtSSxQ4FIYdbRkdRgkf0Sa+OkTiU7jjLyRcknIlAVSgnsEiL1NUGDbHX/sx2Om+kjN66uPSo7iHj12mV/2p+SjURg7Li1/kf0r57L3cTWIFcW2Q2oeKZFJXv/u74DJtXP31Az2a/XtzXkY4+qS6JO+5lkfWE9Adoax6Enz19Qw4s1/mK1rKIXgZbmlSekX6AQjMqbMHYWEESsqVxMWnHXdIKiVLxnRpTdYcnSedvw6we0LU6iBPsQMsRU5LbG6S8wKwtH1lFh1FUP2U4rrSp5w== batstestemail@example.com 2 | -------------------------------------------------------------------------------- /tests/start.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh start" { 6 | dsh start 7 | } 8 | 9 | @test "Checking output of dsh start" { 10 | run dsh start 11 | 12 | [ $status -eq 0 ] 13 | [[ ${lines[0]} =~ "Starting services..." ]] 14 | [[ ${lines[1]} =~ "druded7testing" ]] 15 | [[ ${lines[2]} =~ "druded7testing" ]] 16 | [[ ${lines[3]} =~ "druded7testing" ]] 17 | [[ ${lines[4]} =~ "Connecting vhost-proxy to networks..." ]] 18 | [[ ${lines[5]} =~ "Container and host" ]] 19 | } 20 | 21 | @test "Checking output of dsh up" { 22 | run dsh up 23 | 24 | [ $status -eq 0 ] 25 | [[ ${lines[0]} =~ "Starting services..." ]] 26 | [[ ${lines[1]} =~ "druded7testing" ]] 27 | [[ ${lines[2]} =~ "druded7testing" ]] 28 | [[ ${lines[3]} =~ "druded7testing" ]] 29 | [[ ${lines[4]} =~ "Connecting vhost-proxy to networks..." ]] 30 | [[ ${lines[5]} =~ "Container and host" ]] 31 | } 32 | 33 | @test "Checking dsh _start_containters function" { 34 | run _start_containers 35 | 36 | [ $status -eq 0 ] 37 | [[ ${lines[0]} =~ "Starting services..." ]] 38 | [[ ${lines[1]} =~ "druded7testing" ]] 39 | [[ ${lines[2]} =~ "druded7testing" ]] 40 | [[ ${lines[3]} =~ "druded7testing" ]] 41 | [[ ${lines[4]} =~ "Connecting vhost-proxy to networks..." ]] 42 | [[ ${lines[5]} =~ "Container and host" ]] 43 | } 44 | 45 | -------------------------------------------------------------------------------- /tests/status.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh status" { 6 | dsh status 7 | } 8 | 9 | @test "Checking dsh st" { 10 | dsh st 11 | } 12 | 13 | @test "Checking dsh ps" { 14 | dsh ps 15 | } 16 | 17 | @test "Checking dsh status -a" { 18 | dsh status -a 19 | } 20 | 21 | @test "Checking dsh status" { 22 | dsh status -all 23 | } 24 | 25 | @test "Checking dsh status output" { 26 | run dsh status 27 | 28 | [ $status -eq 0 ] 29 | [[ ${lines[0]} =~ "Name" ]] 30 | [[ ${lines[1]} =~ "---" ]] 31 | [[ ${lines[2]} =~ "druded7testing" ]] 32 | [[ ${lines[3]} =~ "druded7testing" ]] 33 | [[ ${lines[4]} =~ "druded7testing" ]] 34 | } 35 | 36 | @test "Checking dsh st output" { 37 | run dsh st 38 | 39 | [ $status -eq 0 ] 40 | [[ ${lines[0]} =~ "Name" ]] 41 | [[ ${lines[1]} =~ "---" ]] 42 | [[ ${lines[2]} =~ "druded7testing" ]] 43 | [[ ${lines[3]} =~ "druded7testing" ]] 44 | [[ ${lines[4]} =~ "druded7testing" ]] 45 | } 46 | 47 | @test "Checking dsh ps output" { 48 | run dsh ps 49 | 50 | [ $status -eq 0 ] 51 | [[ ${lines[0]} =~ "Name" ]] 52 | [[ ${lines[1]} =~ "---" ]] 53 | [[ ${lines[2]} =~ "druded7testing" ]] 54 | [[ ${lines[3]} =~ "druded7testing" ]] 55 | [[ ${lines[4]} =~ "druded7testing" ]] 56 | } 57 | 58 | @test "Checking dsh status -a output" { 59 | run dsh status -a 60 | 61 | [ $status -eq 0 ] 62 | [[ ${lines[0]} =~ "IMAGE" ]] 63 | [[ ${lines[1]} =~ "blinkreaction" ]] 64 | [[ ${lines[2]} =~ "blinkreaction" ]] 65 | [[ ${lines[3]} =~ "blinkreaction" ]] 66 | } 67 | -------------------------------------------------------------------------------- /tests/stop.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh stop" { 6 | dsh start 7 | } 8 | 9 | @test "Checking output of dsh stop" { 10 | run dsh stop 11 | 12 | [ $status -eq 0 ] 13 | [[ ${lines[0]} =~ "Stopping services..." ]] 14 | } 15 | 16 | @test "Checking output of dsh down" { 17 | run dsh down 18 | 19 | [ $status -eq 0 ] 20 | [[ ${lines[0]} =~ "Stopping services..." ]] 21 | } 22 | 23 | @test "Checking dsh _stop_containers function" { 24 | run _stop_containers 25 | 26 | [ $status -eq 0 ] 27 | [[ ${lines[0]} =~ "Stopping services..." ]] 28 | } 29 | 30 | -------------------------------------------------------------------------------- /tests/troubleshooting.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load "helpers/bats-support/load" 4 | load "helpers/bats-assert/load" 5 | load "helpers/helper" 6 | 7 | # 1.1 8 | @test "1.1 - Keep Docker up to date" { 9 | docker_version=$(docker version | grep -i -A1 '^server' | grep -i 'version:' \ 10 | | awk '{print $NF; exit}' | tr -d '[:alpha:]-,') 11 | docker_current_version="1.11.1" 12 | docker_current_date="2016-04-27" 13 | run do_version_check "$docker_current_version" "$docker_version" 14 | if [ $status -eq 11 ]; then 15 | fail "Using $docker_version, when $docker_current_version is current as of $docker_current_date. Your operating system vendor may provide support and security maintenance for docker." 16 | fi 17 | assert [ $status -eq 9 -o $status -eq 10 ] 18 | } 19 | 20 | # 1.2 21 | @test "1.2 - Check for listening network services" { 22 | # Check for listening network services. 23 | listening_services=$(netstat -na | grep -v tcp6 | grep -v unix | grep -c LISTEN) 24 | if [ "$listening_services" -eq 0 ]; then 25 | fail "Failed to get listening services for check: $BATS_TEST_NAME" 26 | else 27 | if [ "$listening_services" -gt 5 ]; then 28 | fail "Host listening on: $listening_services ports" 29 | fi 30 | fi 31 | } 32 | 33 | # 1.3 34 | @test "1.3 - Use an updated Linux Kernel" { 35 | kernel_version=$(uname -r | cut -d "-" -f 1) 36 | run do_version_check 3.10 "$kernel_version" 37 | assert [ $status -eq 9 -o $status -eq 10 ] 38 | } 39 | 40 | # 1.4 41 | @test "1.4 - Only allow trusted users to control Docker daemon" { 42 | users_string=$(awk -F':' '/^docker/{print $4}' $(get_etc_path)/group) 43 | docker_users=(${users_string//,/ }) 44 | for u in "${docker_users[@]}"; do 45 | found=1 46 | for tu in "${config_trusted_users[@]}"; do 47 | if [ "$u" = "$tu" ]; then 48 | found=0 49 | fi 50 | done 51 | if [ $found -eq 1 ]; then 52 | fail "User $u is not a trusted user!" 53 | fi 54 | done 55 | } 56 | 57 | 58 | # 2.1 59 | @test "2.1 - Opened network traffic between containers" { 60 | result=$(get_docker_effective_command_line_args '--icc') 61 | [ "$output" = "" ] 62 | } 63 | 64 | # 2.2 65 | @test "2.2 - Set the logging level" { 66 | result=$(get_docker_effective_command_line_args '-l') 67 | run grep 'debug' <<< "$result" 68 | assert_failure 69 | } 70 | 71 | # 2.3 72 | @test "2.3 - Allow Docker to make changes to iptables" { 73 | result=$(get_docker_effective_command_line_args '--iptables') 74 | run grep "false" <<< "$result" 75 | assert_failure 76 | } 77 | 78 | # 3.1 79 | @test "3.1 - Verify that docker.service file ownership is set to root:root" { 80 | file="$(get_systemd_service_file docker.service)" 81 | if [ -f "$file" ]; then 82 | if [ "$(stat -c %u%g "$file")" -ne 00 ]; then 83 | fail "Wrong ownership for $file" 84 | fi 85 | fi 86 | } -------------------------------------------------------------------------------- /tests/update.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load dsh_script 4 | 5 | @test "Checking dsh update" { 6 | dsh update 7 | } 8 | 9 | @test "Checking dsh update output" { 10 | run dsh update 11 | 12 | [ $status -eq 0 ] 13 | [[ $output =~ "Use dsh update" ]] 14 | [[ $output =~ "prerequisites" ]] 15 | [[ $output =~ "boot2docker" ]] 16 | [[ $output =~ "images" ]] 17 | [[ $output =~ "dsh" ]] 18 | } --------------------------------------------------------------------------------