Skip to content
This repository has been archived by the owner on Apr 7, 2024. It is now read-only.

Dyanmictraefik #271

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 55 additions & 40 deletions bin/dktl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ main() {

set_project_directory "$@"
set_slug
set_traefik

if [ "$DKTL_MODE" = "DOCKER" ]; then
dktl_docker_run "$@"
Expand All @@ -26,17 +27,17 @@ dktl_run() {
# Check whether dkan-tools' dependencies have been initialized.
if [ -z "$(ls -lha $DKTL_DIRECTORY | grep vendor)" ]; then
echo "Composer Install"
composer install --working-dir=$DKTL_DIRECTORY
composer install --working-dir=$DKTL_DIRECTORY
fi

# Finally, execute the php app.
case $1 in
# Pass through arguments for these. See: https://bit.ly/30IlWGk
drush | phpunit | *test* )
php $DKTL_DIRECTORY/bin/app.php $1 -- "${@:2}"
php "$DKTL_DIRECTORY"/bin/app.php $1 -- "${@:2}"
;;
*)
php $DKTL_DIRECTORY/bin/app.php $1 "${@:2}"
php "$DKTL_DIRECTORY"/bin/app.php $1 "${@:2}"
;;
esac

Expand All @@ -53,7 +54,7 @@ dktl_docker_run() {
# Proxy-pass to docker and save exit status. The command will re-
# run in host mode inside the cli container, so dktl_run will still
# ultimately be run whichever mode dktl is set to.
$BASE_DOCKER_COMPOSE_COMMAND exec $EXEC_OPTS cli dktl "$1" "${@:2}"
dc_base exec $EXEC_OPTS cli dktl "$1" "${@:2}"
exit_status=$?

dktl_docker_cleanup "$@"
Expand Down Expand Up @@ -131,9 +132,10 @@ set_directory() {
if [[ -L $(which dktl) ]]; then
# readlink command needs -f to work properly in linux
if [ "$PLATFORM" = "Linux" ]; then RL_OPT='-f'; fi;
DKTL_DIRECTORY=$(readlink $RL_OPT $DKTL_DIRECTORY)
DKTL_DIRECTORY=$(readlink $RL_OPT "$DKTL_DIRECTORY")
fi
DKTL_DIRECTORY=$(dirname $(dirname $DKTL_DIRECTORY))
DKTL_DIRECTORY=$(dirname "$DKTL_DIRECTORY")
DKTL_DIRECTORY=$(dirname "$DKTL_DIRECTORY")
export DKTL_DIRECTORY
}

Expand All @@ -149,26 +151,25 @@ set_slug() {
fi
}

set_traefik() {
if [ -z "$DKTL_TRAEFIK" ]; then
DKTL_TRAEFIK='dktl-proxy'
export DKTL_TRAEFIK
fi
}

# Set the following variables for use with docker-compose commands:
# DKTL_PROXY_DOMAIN, BASE_DOCKER_COMPOSE_COMMAND, EXEC_OPTS
docker_vars_init() {
if [ -z $WEB_DOMAIN ]; then
WEB_DOMAIN="localtest.me"
fi
if [ -z $DKTL_PROXY_DOMAIN ]; then
export DKTL_PROXY_DOMAIN="$DKTL_SLUG.$WEB_DOMAIN"
export DKTL_PROXY_DOMAIN="${DKTL_SLUG}${DKTL_SUBDOMAIN:+.$DKTL_SUBDOMAIN}.$WEB_DOMAIN"
fi

COMMON_CONF="$DKTL_DIRECTORY/assets/docker/docker-compose.common.yml"
OVERRIDES_CONF="$DKTL_PROJECT_DIRECTORY/src/docker/docker-compose.overrides.yml"
BASE_DOCKER_COMPOSE_COMMAND="docker-compose \
--file $COMMON_CONF \
--project-name "${DKTL_SLUG}" \
--project-directory $DKTL_PROJECT_DIRECTORY"

if [ -f $OVERRIDES_CONF ]; then
BASE_DOCKER_COMPOSE_COMMAND+=" -f $OVERRIDES_CONF"
fi

# Check for interactive shell if DKTL_NO_PTY is not set
if [ ! -z "$DKTL_NO_PTY" ]; then
Expand All @@ -180,53 +181,67 @@ docker_vars_init() {
fi
}

dc_base() {
dc=( docker-compose \
--file "$COMMON_CONF" \
--project-name $DKTL_SLUG \
--project-directory "$DKTL_PROJECT_DIRECTORY" )

if [ -f "$OVERRIDES_CONF" ]; then
dc+=( --file "$OVERRIDES_CONF" )
fi

dc+=( "$@" )
"${dc[@]}"
}


# Set up subdomain with traefic proxy.
proxy_connect () {
network="${DKTL_SLUG}_default"
if docker network connect "$network" dktl-proxy >/dev/null 2>&1; then
echo "Connected dktl-proxy to \"${network}\" network."
if docker network connect "$network" $DKTL_TRAEFIK >/dev/null 2>&1; then
echo "Connected $DKTL_TRAEFIK to \"${network}\" network."
fi
}

dc_up () {
# Check containers state, Run is missing, make sure dktl-proxy is connected
# to the same network.
containers=$($BASE_DOCKER_COMPOSE_COMMAND ps -q)
containers=$(dc_base ps -q)
if [ -z "$containers" ]; then
echo "Starting docker containers."
$BASE_DOCKER_COMPOSE_COMMAND up -d

dc_base up -d
proxy_connect
fi
}

dc_down() {
network="${DKTL_SLUG}_default"

if docker network disconnect "$network" dktl-proxy >/dev/null 2>&1; then
echo "Disconnected dktl-proxy from \"${network}\" network."
if docker network disconnect "$network" $DKTL_TRAEFIK >/dev/null 2>&1; then
echo "Disconnected $DKTL_TRAEFIK from \"${network}\" network."
fi

$BASE_DOCKER_COMPOSE_COMMAND down -v "${@:2}"
dc_base down -v "${@:2}"
}

# Make sure the proxy container is up.
proxy_setup() {
proxy_service_ps=$(docker ps -f 'name=dktl-proxy' --format '{{.Names}}' 2>/dev/null)
proxy_service_ps=$(docker ps -f name="$DKTL_TRAEFIK" --format '{{.Names}}' 2>/dev/null)
if [[ -z $proxy_service_ps ]]; then
echo "Running dktl-proxy.."
echo "Running $DKTL_TRAEFIK.."
# Make sure no old instance is using the name.
docker rm dktl-proxy >/dev/null 2>&1
docker rm $DKTL_TRAEFIK >/dev/null 2>&1
if ! docker run -d -p 8080:8080 -p 80:80 -p 433:433 \
-v '/var/run/docker.sock:/var/run/docker.sock' \
--name 'dktl-proxy' \
--name "$DKTL_TRAEFIK" \
traefik:v2.0 \
--log.level=INFO --api.insecure=true --providers.docker=true \
--providers.docker.exposedbydefault=false --entrypoints.web.address=:80 \
--entrypoints.websecure.address=:443 \
>/dev/null; \
then
echo -n "Failed to start the dktl-proxy container..."
echo -n "Failed to start the $DKTL_TRAEFIK container..."
fi

fi
Expand All @@ -236,7 +251,7 @@ proxy_setup() {
docker_command_intercept() {
if [ "$1" = "docker:compose" ] || [ "$1" = "dc" ]; then
dc_up
$BASE_DOCKER_COMPOSE_COMMAND "${@:2}"
dc_base "${@:2}"
exit 0
elif [ "$1" = "url" ] || [ "$1" = "docker:url" ]; then
echo "http://$DKTL_PROXY_DOMAIN"
Expand All @@ -247,44 +262,44 @@ docker_command_intercept() {
elif [ "$1" = "docker:proxy-connect" ] || [ "$1" = "proxy:connect" ]; then
proxy_connect
# Restart container to refresh config.
$BASE_DOCKER_COMPOSE_COMMAND restart
dc_base restart
exit 0
elif [ "$1" = "docker:proxy-kill" ] || [ "$1" = "proxy:kill" ]; then
echo "Removing dktl-proxy ..."
docker stop dktl-proxy >/dev/null 2>&1
docker rm dktl-proxy >/dev/null 2>&1
echo "Removing $DKTL_TRAEFIK ..."
docker stop $DKTL_TRAEFIK >/dev/null 2>&1
docker rm $DKTL_TRAEFIK >/dev/null 2>&1
exit 0
fi
}

# The containers are running, set DKTL inside the cli container.
dktl_set_alias() {
ALIAS="$($BASE_DOCKER_COMPOSE_COMMAND exec $EXEC_OPTS cli which dktl)"
ALIAS="$(dc_base exec $EXEC_OPTS cli which dktl)"
if [ -z "$ALIAS" ]; then
$BASE_DOCKER_COMPOSE_COMMAND exec $EXEC_OPTS cli \
dc_base exec $EXEC_OPTS cli \
chmod 777 /usr/local/dkan-tools/bin/dktl
$BASE_DOCKER_COMPOSE_COMMAND exec $EXEC_OPTS cli \
dc_base exec $EXEC_OPTS cli \
ln -s /usr/local/dkan-tools/bin/dktl /usr/local/bin/dktl
fi
}

dktl_docker_cleanup() {
# Reset web and cli containers if xdebug.
if [ $? -eq 0 ] && [[ $1 == "xdebug"* ]]; then
$BASE_DOCKER_COMPOSE_COMMAND restart web
$BASE_DOCKER_COMPOSE_COMMAND restart cli
dc_base restart web
dc_base restart cli
fi

# Proxy connect if we just ran make.
if [ $? -eq 0 ] && [[ $1 == "init"* ]]; then
proxy_connect
$BASE_DOCKER_COMPOSE_COMMAND restart web
dc_base restart web
fi

if [ -z "$DKTL_CHOWN" ] || [ "$DKTL_CHOWN" = "TRUE" ]; then
# Docker creates files that appear as owned by root on host. Fix:
if [ -n "$(find "$DKTL_PROJECT_DIRECTORY" -user root -print -quit)" ]; then
$BASE_DOCKER_COMPOSE_COMMAND exec $EXEC_OPTS cli chown -R `id -u`:`id -g` /var/www
dc_base exec $EXEC_OPTS cli chown -R `id -u`:`id -g` /var/www
fi
fi
}
Expand Down
86 changes: 60 additions & 26 deletions src/Command/InitCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,28 @@ class InitCommands extends \Robo\Tasks
* @option str dkan
* DKAN version (expressed as composer constraint). Use 2.x-dev for current
* bleeding edge.
* @option bool dkan-local
* Use DKAN from a "dkan" folder in your project root instead of composer.
* If no version constraint is provided via the --dkan option, dktl will
* attempt to generate one based on the current git branch in "dkan".
*/
public function init($opts = ['drupal' => '9.0.0', 'dkan' => null])
public function init($opts = ['drupal' => '9.0.0', 'dkan' => null, 'dkan-local' => false])
{
// Validate version is semantic and at least the minimum set
// in DrupalProjectTrait.
if (!$this->drupalProjectValidateVersion($opts['drupal'])) {
exit;
}
$this->initDrupal($opts['drupal']);
$this->initConfig();
$this->initSrc();
$this->initDrupal($opts['drupal']);
if ($opts['dkan-local']) {
$this->initLocalDkan();
$version = $this->localDkanVersion();
}
if (isset($version) && !$opts['dkan']) {
$opts['dkan'] = $version;
}
$this->initDkan($opts['dkan']);
}

Expand All @@ -41,34 +52,27 @@ public function init($opts = ['drupal' => '9.0.0', 'dkan' => null])
private function initConfig()
{
$this->io()->section('Initializing dktl configuration');
if (file_exists('dktl.yml') && file_exists('src')) {
$this->io()->note("This project has already been initialized.");
exit;
}

if (file_exists('dktl.yml')) {
$this->io()->warning('The dktl.yml file already exists in this directory; skipping.');
} else {
$this->createDktlYmlFile();
$this->io()->note('The dktl.yml file already exists in this directory; skipping.');
return;
}
$f = Util::getProjectDirectory() . '/dktl.yml';
$result = $this->taskExec('touch')->arg($f)->run();
$this->directoryAndFileCreationCheck($result, $f);
}

/**
* Set up the src directory in a new project.
*/
private function initSrc()
{
$this->io()->section('Initializing src directory');
if (file_exists('src')) {
$this->io()->warning('The src directory already exists in this directory; skipping.');
exit;
$this->io()->section('Initializing project code directory in /src');
if (is_dir('src')) {
$this->io()->note("A /src directory already exists; skipping.");
return;
}

$this->_mkdir('src');
$this->_mkdir('docroot');

$directories = ['docker', 'modules', 'themes', 'site', 'test', 'script', 'command'];

foreach ($directories as $directory) {
$dir = "src/{$directory}";
$result = $this->_mkdir($dir);
Expand Down Expand Up @@ -97,13 +101,6 @@ private function createSiteCommands()
$this->directoryAndFileCreationCheck($result, $f);
}

private function createDktlYmlFile()
{
$f = Util::getProjectDirectory() . '/dktl.yml';
$result = $this->taskExec('touch')->arg($f)->run();
$this->directoryAndFileCreationCheck($result, $f);
}

/**
* Set up scripts directory and copy in standard deploy.sh scripts.
*/
Expand Down Expand Up @@ -198,13 +195,15 @@ private function initCircleCI()
}

/**
* Create a new Drupal project in the current directory.
* Create a new Drupal project in the current directory. If one exists, it
* will be overwritten.
*
* @param mixed $drupalVersion
* Drupal version to use, expressed as Composer constraint.
*/
public function initDrupal($drupalVersion)
{
$this->io()->section('Creating new Drupal project.');
Util::prepareTmp();

// Composer's create-project requires an empty folder, so run it in
Expand All @@ -215,6 +214,9 @@ public function initDrupal($drupalVersion)
// Modify project's scaffold and installation paths to `docroot`, then
// install Drupal in it.
$this->drupalProjectSetDocrootPath();
if (!is_dir('docroot')) {
$this->_mkdir('docroot');
}

Util::cleanupTmp();
}
Expand All @@ -229,9 +231,41 @@ public function initDrupal($drupalVersion)
*/
public function initDkan(string $version = null)
{
$this->io()->section('Adding DKAN project dependency.');
$this->taskComposerRequire()
->dependency('getdkan/dkan', $version)
->option('--no-update')
->run();
}

/**
* Add composer repository for /dkan folder in project.
*/
private function initLocalDkan()
{
$this->io()->section('Adding local DKAN repository in /dkan.');
$this->taskComposerConfig()
->repository('getdkan', 'dkan', 'path')
->run();
}

/**
* Get branch of local DKAN clone.
*/
private function localDkanVersion()
{
if (!is_dir('dkan')) {
throw new \Exception('No local dkan folder in project root.');
}
$result = $this->taskGitStack()
->dir('dkan')
->exec("rev-parse --abbrev-ref HEAD")
->printOutput(false)
->run();

if ($result->getExitCode() === 0) {
$branch = $result->getMessage();
return is_numeric(substr($branch, 0, 1)) ? "${branch}-dev" : "dev-${branch}";
}
}
}
Loading