From 0d3ea194ab5c1b20148b497788051f6dc3c9ffb1 Mon Sep 17 00:00:00 2001 From: Rick Bouma Date: Tue, 10 Jun 2025 21:27:24 +0200 Subject: [PATCH 1/5] add magento2-init command, improve usage loading with dynamic paths, and enhance global/environment-specific config handling --- bin/roll | 2 +- commands/registry.cmd | 30 +------------------ commands/usage.cmd | 37 ++++++++++++++++------- commands/usage.help | 1 + utils/config.sh | 43 ++++++++++++++++++++++++++- utils/registry.sh | 68 ++++++++++++++++++++++++++++++++++++------- 6 files changed, 129 insertions(+), 52 deletions(-) diff --git a/bin/roll b/bin/roll index fdb59ba..a124320 100755 --- a/bin/roll +++ b/bin/roll @@ -40,7 +40,7 @@ declare ROLL_PARAMS=() declare ROLL_CMD_VERB= declare ROLL_CMD_EXEC= declare ROLL_CMD_HELP= -declare ROLL_CMD_ANYARGS=(svc env db redis sync shell debug rootnotty rootshell clinotty root node npm cli copyfromcontainer copytocontainer composer grunt magento magerun backup restore restore-full duplicate) +declare ROLL_CMD_ANYARGS=(svc env db redis sync shell debug rootnotty rootshell clinotty root node npm cli copyfromcontainer copytocontainer composer grunt magento magerun backup restore restore-full duplicate magento2-init) ## parse first argument as command and determine validity if (( "$#" )); then diff --git a/commands/registry.cmd b/commands/registry.cmd index 903e7e7..4cc7f9f 100644 --- a/commands/registry.cmd +++ b/commands/registry.cmd @@ -163,35 +163,7 @@ case "${ROLL_PARAMS[0]}" in paths) # Show command search paths and their priorities - echo -e "\033[33mCommand Search Paths (by priority):\033[0m" - echo "" - - echo -e "\033[36mGlobal Command Paths:\033[0m" - for search_path in "${ROLL_COMMAND_SEARCH_PATHS[@]}"; do - priority="${search_path%%:*}" - directory="${search_path##*:}" - status="❌" - [[ -d "$directory" ]] && status="✅" - - printf " %s Priority %s: %s\n" "$status" "$priority" "$directory" - done - - if [[ -n "${ROLL_ENV_TYPE}" ]]; then - echo "" - echo -e "\033[36mEnvironment-Specific Paths (${ROLL_ENV_TYPE}):\033[0m" - while IFS= read -r env_path; do - [[ -z "$env_path" ]] && continue - priority="${env_path%%:*}" - directory="${env_path##*:}" - status="❌" - [[ -d "$directory" ]] && status="✅" - - printf " %s Priority %s: %s\n" "$status" "$priority" "$directory" - done < <(getEnvCommandPaths) - else - echo "" - info "No environment loaded - environment-specific paths not shown" - fi + showRegistryPaths ;; *) diff --git a/commands/usage.cmd b/commands/usage.cmd index d87b712..6d7fe4b 100644 --- a/commands/usage.cmd +++ b/commands/usage.cmd @@ -6,21 +6,38 @@ ROLL_ENV_PATH="$(locateEnvPath 2>/dev/null)" || true if [[ -n "$ROLL_ENV_PATH" ]];then loadEnvConfig "${ROLL_ENV_PATH}" || true - if [[ -n "$ROLL_ENV_TYPE" && -f "${ROLL_DIR}/commands/${ROLL_ENV_TYPE}/usage.help" ]]; then - source "${ROLL_DIR}/commands/${ROLL_ENV_TYPE}/usage.help" - fi - if [[ -n "$ROLL_ENV_TYPE" && -f "${HOME}/.roll/reclu/${ROLL_ENV_TYPE}/usage.help" ]]; then - source "${HOME}/.roll/reclu/${ROLL_ENV_TYPE}/usage.help" - fi + + # Pre-load environment-specific usage fragments to set variables for global usage.help + if [[ -n "$ROLL_ENV_TYPE" ]]; then + # Load system environment-specific usage fragments + if [[ -f "${ROLL_DIR}/commands/${ROLL_ENV_TYPE}/usage.help" ]]; then + source "${ROLL_DIR}/commands/${ROLL_ENV_TYPE}/usage.help" + fi + + # Load global environment-specific usage fragments (new structure) + if [[ -f "${ROLL_HOME_DIR:-$HOME/.roll}/commands/${ROLL_ENV_TYPE}/usage.help" ]]; then + source "${ROLL_HOME_DIR:-$HOME/.roll}/commands/${ROLL_ENV_TYPE}/usage.help" + fi + + # Load global environment-specific usage fragments (legacy structure) + if [[ -f "${ROLL_HOME_DIR:-$HOME/.roll}/reclu/${ROLL_ENV_TYPE}/usage.help" ]]; then + source "${ROLL_HOME_DIR:-$HOME/.roll}/reclu/${ROLL_ENV_TYPE}/usage.help" + fi + fi fi - -## load usage info for the given command falling back on default usage text +## Load usage info for the given command falling back on default usage text if [[ -f "${ROLL_CMD_HELP}" ]]; then + # Load command-specific help file source "${ROLL_CMD_HELP}" -elif [[ -f "${HOME}/.roll/reclu/usage.help" ]]; then - source "${HOME}/.roll/reclu/usage.help" +elif [[ -f "${ROLL_HOME_DIR:-$HOME/.roll}/commands/usage.help" ]]; then + # Load global usage (variables are already set above) + source "${ROLL_HOME_DIR:-$HOME/.roll}/commands/usage.help" +elif [[ -f "${ROLL_HOME_DIR:-$HOME/.roll}/reclu/usage.help" ]]; then + # Load legacy global usage + source "${ROLL_HOME_DIR:-$HOME/.roll}/reclu/usage.help" else + # Load system default usage (fragments already loaded above if needed) source "${ROLL_DIR}/commands/usage.help" fi diff --git a/commands/usage.help b/commands/usage.help index 0087eed..9d64daf 100755 --- a/commands/usage.help +++ b/commands/usage.help @@ -48,6 +48,7 @@ RollDev version $(cat ${ROLL_DIR}/version) \033[33mCommands:\033[0m svc Orchestrates global services such as traefik, portainer and dnsmasq via docker-compose env-init Configure environment by adding \033[31m'.env.roll'\033[0m file to the current working directory + magento2-init Scaffold a complete Magento 2 project from scratch env Controls an environment from any point within the root project directory config Manage and validate Roll configuration (see \033[31m'roll config -h'\033[0m for details) registry Manage and inspect command registry (see \033[31m'roll registry -h'\033[0m for details) diff --git a/utils/config.sh b/utils/config.sh index dcbb70a..d485b01 100644 --- a/utils/config.sh +++ b/utils/config.sh @@ -140,6 +140,11 @@ function initConfigSchema() { ROLL_CONFIG_SCHEMA_KEYS+=(ROLL_ENV_SHELL_COMMAND); ROLL_CONFIG_SCHEMA_VALUES+=("string:bash") ROLL_CONFIG_SCHEMA_KEYS+=(ROLL_ENV_SHELL_DEBUG_CONTAINER); ROLL_CONFIG_SCHEMA_VALUES+=("string:php-debug") + # Global service configuration + ROLL_CONFIG_SCHEMA_KEYS+=(ROLL_SERVICE_STARTPAGE); ROLL_CONFIG_SCHEMA_VALUES+=("boolean:1") + ROLL_CONFIG_SCHEMA_KEYS+=(ROLL_SERVICE_PORTAINER); ROLL_CONFIG_SCHEMA_VALUES+=("boolean:1") + ROLL_CONFIG_SCHEMA_KEYS+=(ROLL_SERVICE_DOMAIN); ROLL_CONFIG_SCHEMA_VALUES+=("string:optional") + # XDebug configuration ROLL_CONFIG_SCHEMA_KEYS+=(XDEBUG_CONNECT_BACK_HOST); ROLL_CONFIG_SCHEMA_VALUES+=("string:optional") ROLL_CONFIG_SCHEMA_KEYS+=(XDEBUG_VERSION); ROLL_CONFIG_SCHEMA_VALUES+=("string:debug") @@ -312,7 +317,28 @@ function loadRollConfig() { # Initialize schema if not done initConfigSchema - # Load configuration from file + # Load global configuration first from ROLL_HOME_DIR + local global_config_loaded=0 + + # Check for new-style global config file + if [[ -f "${ROLL_HOME_DIR}/.env.roll" ]]; then + if loadConfigFromFile "${ROLL_HOME_DIR}/.env.roll"; then + global_config_loaded=1 + else + warning "Failed to load global configuration from ${ROLL_HOME_DIR}/.env.roll" + fi + fi + + # Check for legacy global config file + if [[ -f "${ROLL_HOME_DIR}/.env" ]]; then + if loadConfigFromFile "${ROLL_HOME_DIR}/.env"; then + global_config_loaded=1 + else + warning "Failed to load global configuration from ${ROLL_HOME_DIR}/.env" + fi + fi + + # Load project-specific configuration (this will override global settings) if ! loadConfigFromFile "$config_file"; then return 1 fi @@ -508,6 +534,21 @@ function showConfig() { echo -e "\033[33mRoll Configuration:\033[0m" echo "Environment: ${ROLL_ENV_NAME:-} (${ROLL_ENV_TYPE:-})" echo "Platform: ${ROLL_ENV_SUBT:-}" + + # Show loaded configuration files + if [[ ${#ROLL_CONFIG_LOADED_FILES[@]} -gt 0 ]]; then + echo "" + echo -e "\033[33mLoaded configuration files:\033[0m" + local loaded_file + for loaded_file in "${ROLL_CONFIG_LOADED_FILES[@]}"; do + if [[ "$loaded_file" =~ ${ROLL_HOME_DIR} ]]; then + echo " ${loaded_file} (global)" + else + echo " ${loaded_file} (project)" + fi + done + fi + echo "" local i=0 diff --git a/utils/registry.sh b/utils/registry.sh index 96b56d5..4bd57bb 100644 --- a/utils/registry.sh +++ b/utils/registry.sh @@ -15,11 +15,18 @@ ROLL_REGISTRY_PRIORITIES=() ROLL_REGISTRY_INITIALIZED=0 # Command search paths with priorities (lower number = higher priority) -ROLL_COMMAND_SEARCH_PATHS=( - "2:${ROLL_HOME_DIR}/commands" - "3:${ROLL_HOME_DIR}/reclu" - "4:${ROLL_DIR}/commands" -) +# Note: ROLL_HOME_DIR may not be available when this script is sourced, so we define this dynamically +ROLL_COMMAND_SEARCH_PATHS=() + +# Function to get command search paths (called when registry is initialized) +function getCommandSearchPaths() { + local search_paths=( + "2:${ROLL_HOME_DIR:-$HOME/.roll}/commands" + "3:${ROLL_HOME_DIR:-$HOME/.roll}/reclu" + "4:${ROLL_DIR}/commands" + ) + printf '%s\n' "${search_paths[@]}" +} # Environment-specific command paths (added dynamically if env is available) function getEnvCommandPaths() { @@ -32,7 +39,11 @@ function getEnvCommandPaths() { # Add environment-specific commands if ROLL_ENV_TYPE is available if [[ -n "${ROLL_ENV_TYPE}" ]]; then - [[ -d "${ROLL_HOME_DIR}/reclu/${ROLL_ENV_TYPE}" ]] && env_paths+=("1:${ROLL_HOME_DIR}/reclu/${ROLL_ENV_TYPE}") + # Check for commands in ${ROLL_HOME_DIR}/commands/${ROLL_ENV_TYPE} (new structure) + [[ -d "${ROLL_HOME_DIR:-$HOME/.roll}/commands/${ROLL_ENV_TYPE}" ]] && env_paths+=("1:${ROLL_HOME_DIR:-$HOME/.roll}/commands/${ROLL_ENV_TYPE}") + # Check for commands in ${ROLL_HOME_DIR}/reclu/${ROLL_ENV_TYPE} (legacy structure) + [[ -d "${ROLL_HOME_DIR:-$HOME/.roll}/reclu/${ROLL_ENV_TYPE}" ]] && env_paths+=("1:${ROLL_HOME_DIR:-$HOME/.roll}/reclu/${ROLL_ENV_TYPE}") + # System environment-specific commands [[ -d "${ROLL_DIR}/commands/${ROLL_ENV_TYPE}" ]] && env_paths+=("2:${ROLL_DIR}/commands/${ROLL_ENV_TYPE}") fi @@ -164,11 +175,10 @@ function initializeRegistry() { [[ -n "$env_path" ]] && scanCommandDirectory "$env_path" "environment" done < <(getEnvCommandPaths) - # Scan global command directories - local search_path - for search_path in "${ROLL_COMMAND_SEARCH_PATHS[@]}"; do - scanCommandDirectory "$search_path" "global" - done + # Scan global command directories using dynamic search paths + while IFS= read -r search_path; do + [[ -n "$search_path" ]] && scanCommandDirectory "$search_path" "global" + done < <(getCommandSearchPaths) ROLL_REGISTRY_INITIALIZED=1 } @@ -355,6 +365,42 @@ function showRegistryStats() { done } +## Display command search paths +function showRegistryPaths() { + echo "Command Search Paths (by priority):" + echo "" + + # Show environment-specific paths first + local env_paths + env_paths=($(getEnvCommandPaths)) + if [[ ${#env_paths[@]} -gt 0 ]]; then + echo "Environment-Specific Paths (${ROLL_ENV_TYPE:-unknown}):" + local env_path + for env_path in "${env_paths[@]}"; do + local priority="${env_path%%:*}" + local directory="${env_path##*:}" + if [[ -d "$directory" ]]; then + echo " ✅ Priority $priority: $directory" + else + echo " ❌ Priority $priority: $directory" + fi + done + echo "" + fi + + # Show global command paths + echo "Global Command Paths:" + while IFS= read -r search_path; do + local priority="${search_path%%:*}" + local directory="${search_path##*:}" + if [[ -d "$directory" ]]; then + echo " ✅ Priority $priority: $directory" + else + echo " ❌ Priority $priority: $directory" + fi + done < <(getCommandSearchPaths) +} + ## Export command list for external tools function exportCommands() { local format="${1:-simple}" From a028ac136373e4e082b62cbb6f2e489f4bf69a09 Mon Sep 17 00:00:00 2001 From: Rick Bouma Date: Tue, 10 Jun 2025 21:27:43 +0200 Subject: [PATCH 2/5] add magento2-init command for project initialization with dynamic configuration and compatibility checks --- commands/magento2-init.cmd | 699 ++++++++++++++++++++++++++++++++++++ commands/magento2-init.help | 77 ++++ 2 files changed, 776 insertions(+) create mode 100755 commands/magento2-init.cmd create mode 100755 commands/magento2-init.help diff --git a/commands/magento2-init.cmd b/commands/magento2-init.cmd new file mode 100755 index 0000000..41f80a0 --- /dev/null +++ b/commands/magento2-init.cmd @@ -0,0 +1,699 @@ +#!/usr/bin/env bash +[[ ! ${ROLL_DIR} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!\033[0m" && exit 1 + +# Default Magento version (minimum supported: 2.4.6) +DEFAULT_MAGENTO_VERSION="2.4.x" + +# Extract parameters +PROJECT_NAME="${ROLL_PARAMS[0]:-}" +MAGENTO_VERSION="${ROLL_PARAMS[1]:-$DEFAULT_MAGENTO_VERSION}" +TARGET_DIR="${ROLL_PARAMS[2]:-}" + +# Function to display usage information +show_usage() { + echo -e "\033[33mUsage:\033[0m" + echo " roll magento2-init [magento_version] [target_directory]" + echo "" + echo -e "\033[33mArguments:\033[0m" + echo " project_name Name of the Magento 2 project" + echo " magento_version Magento version to install (default: 2.4.x)" + echo " Supports: 2.4.6+, 2.4.7, 2.4.7-p3, 2.4.8, etc." + echo " Minimum supported version: 2.4.6" + echo " target_directory Directory to create project in (default: current directory)" + echo "" + echo -e "\033[33mExamples:\033[0m" + echo " roll magento2-init myproject" + echo " roll magento2-init myproject 2.4.7" + echo " roll magento2-init myproject 2.4.7-p3" + echo " roll magento2-init myproject 2.4.8" + echo " roll magento2-init myproject 2.4.x ~/Sites/myproject" + exit 1 +} + +# Validate project name +if [ -z "${PROJECT_NAME}" ]; then + echo -e "\033[31mError: Project name is required.\033[0m" + show_usage +fi + +# Validate project name format +if [[ ! "${PROJECT_NAME}" =~ ^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$ ]]; then + echo -e "\033[31mError: Project name should contain only lowercase letters, numbers, and hyphens.\033[0m" + echo -e "\033[31mIt should start and end with a letter or number.\033[0m" + exit 1 +fi + +# Validate Magento version format and minimum version (2.4.6+) +if [[ ! "${MAGENTO_VERSION}" =~ ^2\.4(\.[6-9x]+)?(-p[0-9]+)?$ ]] && [[ ! "${MAGENTO_VERSION}" =~ ^2\.[5-9](\.[0-9x]+)?(-p[0-9]+)?$ ]]; then + echo -e "\033[31mError: Invalid Magento version format.\033[0m" + echo -e "\033[31mSupported formats: 2.4.6+, 2.4.7, 2.4.7-p3, 2.4.8, etc.\033[0m" + exit 1 +fi + +# Check minimum version requirement (2.4.6+) +if [[ "${MAGENTO_VERSION}" =~ ^2\.4\.([0-5])($|-p) ]]; then + echo -e "\033[31mError: Magento version ${MAGENTO_VERSION} is not supported.\033[0m" + echo -e "\033[31mMinimum supported version is 2.4.6\033[0m" + echo -e "\033[33mFor older Magento versions, please use manual installation or upgrade to 2.4.6+\033[0m" + exit 1 +fi + +# Function to get compatible software versions based on Magento version (2.4.6+ only) +get_software_versions() { + local magento_version="$1" + local base_version + local patch_version="" + + # Extract base version and patch version + if [[ "${magento_version}" =~ ^([0-9]+\.[0-9]+\.[0-9x]+)(-p([0-9]+))?$ ]]; then + base_version="${BASH_REMATCH[1]}" + patch_version="${BASH_REMATCH[3]:-0}" + else + base_version="${magento_version}" + patch_version="0" + fi + + # Set default values for 2.4.6+ + PHP_VERSION="8.2" + DB_DISTRIBUTION_VERSION="10.6" + ELASTICSEARCH_VERSION="7.17" + REDIS_VERSION="7.0" + RABBITMQ_VERSION="3.9" + VARNISH_VERSION="7.1" + COMPOSER_VERSION="2" + NODE_VERSION="19" + + # Version mapping based on Magento compatibility matrix (2.4.6+ only) + case "${base_version}" in + "2.4.9"*) + PHP_VERSION="8.4" + DB_DISTRIBUTION_VERSION="11.4" + ELASTICSEARCH_VERSION="2.19" # OpenSearch + REDIS_VERSION="8" # Valkey + RABBITMQ_VERSION="4.1" + VARNISH_VERSION="7.7" + COMPOSER_VERSION="2" + ;; + "2.4.8"*) + PHP_VERSION="8.3" + DB_DISTRIBUTION_VERSION="11.4" + ELASTICSEARCH_VERSION="2.19" # OpenSearch + REDIS_VERSION="8" # Valkey + RABBITMQ_VERSION="4.1" + VARNISH_VERSION="7.7" + COMPOSER_VERSION="2" + ;; + "2.4.7"*) + PHP_VERSION="8.3" + if [[ "${patch_version}" -ge 6 ]]; then + DB_DISTRIBUTION_VERSION="10.11" + REDIS_VERSION="7.2" + VARNISH_VERSION="7.7" + COMPOSER_VERSION="2" + elif [[ "${patch_version}" -ge 3 ]]; then + DB_DISTRIBUTION_VERSION="10.6" + REDIS_VERSION="7.2" + VARNISH_VERSION="7.5" + COMPOSER_VERSION="2" + else + DB_DISTRIBUTION_VERSION="10.6" + REDIS_VERSION="7.2" + VARNISH_VERSION="7.5" + COMPOSER_VERSION="2" + fi + ELASTICSEARCH_VERSION="7.17" + RABBITMQ_VERSION="3.13" + ;; + "2.4.6"*) + PHP_VERSION="8.2" + DB_DISTRIBUTION_VERSION="10.6" + ELASTICSEARCH_VERSION="7.17" + REDIS_VERSION="7.0" + RABBITMQ_VERSION="3.9" + VARNISH_VERSION="7.1" + COMPOSER_VERSION="2" + if [[ "${patch_version}" -ge 8 ]]; then + REDIS_VERSION="7.2" + VARNISH_VERSION="7.5" + fi + ;; + "2.4.x"|"2.4"*) + # Default to latest stable versions for 2.4.x + PHP_VERSION="8.3" + DB_DISTRIBUTION_VERSION="10.6" + ELASTICSEARCH_VERSION="7.17" + REDIS_VERSION="7.2" + RABBITMQ_VERSION="3.13" + VARNISH_VERSION="7.5" + COMPOSER_VERSION="2" + ;; + esac + + echo -e "\033[33mConfigured software versions for Magento ${magento_version}:\033[0m" + echo -e " PHP: ${PHP_VERSION}" + echo -e " MariaDB: ${DB_DISTRIBUTION_VERSION}" + if [[ "${ELASTICSEARCH_VERSION}" == "2."* ]]; then + echo -e " Search Engine: OpenSearch ${ELASTICSEARCH_VERSION}" + else + echo -e " Search Engine: Elasticsearch ${ELASTICSEARCH_VERSION}" + fi + echo -e " Redis: ${REDIS_VERSION}" + echo -e " RabbitMQ: ${RABBITMQ_VERSION}" + echo -e " Varnish: ${VARNISH_VERSION}" + echo -e " Composer: ${COMPOSER_VERSION}" + echo -e " Node.js: ${NODE_VERSION}" +} + +# Set target directory +if [ -z "${TARGET_DIR}" ]; then + TARGET_DIR="$(pwd)/${PROJECT_NAME}" +else + # Handle relative paths and ensure absolute path + if [[ "${TARGET_DIR}" != /* ]]; then + TARGET_DIR="$(pwd)/${TARGET_DIR}" + fi + TARGET_DIR="${TARGET_DIR}/${PROJECT_NAME}" +fi + +echo -e "\033[32mInitializing Magento 2 project: ${PROJECT_NAME}\033[0m" +echo -e "\033[32mMagento version: ${MAGENTO_VERSION}\033[0m" +echo -e "\033[32mTarget directory: ${TARGET_DIR}\033[0m" + +# Check if target directory already exists +if [ -d "${TARGET_DIR}" ]; then + echo -e "\033[31mError: Directory ${TARGET_DIR} already exists.\033[0m" + exit 1 +fi + +# Create project directory +echo -e "\033[36m[1/10] Creating project directory...\033[0m" +mkdir -p "${TARGET_DIR}" +cd "${TARGET_DIR}" + +# Get compatible software versions for this Magento version +echo -e "\033[36m[2/10] Determining compatible software versions...\033[0m" +get_software_versions "${MAGENTO_VERSION}" + +# Initialize environment +echo -e "\033[36m[3/10] Initializing environment configuration...\033[0m" +"${ROLL_DIR}/bin/roll" env-init "${PROJECT_NAME}" magento2 + +# Update .env.roll with version-specific software versions +echo -e "\033[36m[4/10] Updating environment with compatible software versions...\033[0m" +ENV_FILE="${TARGET_DIR}/.env.roll" + +# Update software versions in .env.roll file +sed -i.bak "s/^PHP_VERSION=.*/PHP_VERSION=${PHP_VERSION}/" "${ENV_FILE}" +sed -i.bak "s/^DB_DISTRIBUTION_VERSION=.*/DB_DISTRIBUTION_VERSION=${DB_DISTRIBUTION_VERSION}/" "${ENV_FILE}" +sed -i.bak "s/^COMPOSER_VERSION=.*/COMPOSER_VERSION=${COMPOSER_VERSION}/" "${ENV_FILE}" +sed -i.bak "s/^NODE_VERSION=.*/NODE_VERSION=${NODE_VERSION}/" "${ENV_FILE}" +sed -i.bak "s/^RABBITMQ_VERSION=.*/RABBITMQ_VERSION=${RABBITMQ_VERSION}/" "${ENV_FILE}" +sed -i.bak "s/^VARNISH_VERSION=.*/VARNISH_VERSION=${VARNISH_VERSION}/" "${ENV_FILE}" + +# Handle search engine configuration (OpenSearch vs Elasticsearch) +if [[ "${ELASTICSEARCH_VERSION}" == "2."* ]]; then + # Use OpenSearch for newer Magento versions (2.4.8+) + OPENSEARCH_VERSION="${ELASTICSEARCH_VERSION}" + sed -i.bak "s/^ROLL_ELASTICSEARCH=.*/ROLL_ELASTICSEARCH=0/" "${ENV_FILE}" + sed -i.bak "s/^ROLL_OPENSEARCH=.*/ROLL_OPENSEARCH=1/" "${ENV_FILE}" + # Set OpenSearch version + if ! grep -q "^OPENSEARCH_VERSION=" "${ENV_FILE}"; then + echo "OPENSEARCH_VERSION=${OPENSEARCH_VERSION}" >> "${ENV_FILE}" + else + sed -i.bak "s/^OPENSEARCH_VERSION=.*/OPENSEARCH_VERSION=${OPENSEARCH_VERSION}/" "${ENV_FILE}" + fi + # Keep Elasticsearch version for compatibility, but disabled + sed -i.bak "s/^ELASTICSEARCH_VERSION=.*/ELASTICSEARCH_VERSION=7.17/" "${ENV_FILE}" + # Set actual search engine version for configuration + ELASTICSEARCH_VERSION="7.17" # Fallback version + echo -e " OpenSearch: ${OPENSEARCH_VERSION} (primary)" + echo -e " Elasticsearch: ${ELASTICSEARCH_VERSION} (fallback)" +else + # Use Elasticsearch for older versions + sed -i.bak "s/^ROLL_ELASTICSEARCH=.*/ROLL_ELASTICSEARCH=1/" "${ENV_FILE}" + sed -i.bak "s/^ROLL_OPENSEARCH=.*/ROLL_OPENSEARCH=0/" "${ENV_FILE}" + sed -i.bak "s/^ELASTICSEARCH_VERSION=.*/ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION}/" "${ENV_FILE}" + # Ensure OpenSearch is disabled + if grep -q "^OPENSEARCH_VERSION=" "${ENV_FILE}"; then + sed -i.bak "/^OPENSEARCH_VERSION=/d" "${ENV_FILE}" + fi +fi + +# Handle Redis vs Valkey (Valkey for version 8+) +if [[ "${REDIS_VERSION}" == "8" ]]; then + # Use Valkey (Redis fork) for version 8 + sed -i.bak "s/^ROLL_REDIS=.*/ROLL_REDIS=0/" "${ENV_FILE}" + sed -i.bak "s/^ROLL_DRAGONFLY=.*/ROLL_DRAGONFLY=1/" "${ENV_FILE}" + # Add Dragonfly/Valkey version if not present + if ! grep -q "^DRAGONFLY_VERSION=" "${ENV_FILE}"; then + echo "DRAGONFLY_VERSION=${REDIS_VERSION}" >> "${ENV_FILE}" + else + sed -i.bak "s/^DRAGONFLY_VERSION=.*/DRAGONFLY_VERSION=${REDIS_VERSION}/" "${ENV_FILE}" + fi +else + # Use Redis for traditional versions + sed -i.bak "s/^ROLL_REDIS=.*/ROLL_REDIS=1/" "${ENV_FILE}" + sed -i.bak "s/^ROLL_DRAGONFLY=.*/ROLL_DRAGONFLY=0/" "${ENV_FILE}" + sed -i.bak "s/^REDIS_VERSION=.*/REDIS_VERSION=${REDIS_VERSION}/" "${ENV_FILE}" +fi + +# Clean up backup file +rm -f "${ENV_FILE}.bak" + +# Sign SSL certificate +echo -e "\033[36m[5/10] Signing SSL certificate...\033[0m" +"${ROLL_DIR}/bin/roll" sign-certificate "${PROJECT_NAME}.test" + +# Start environment +echo -e "\033[36m[6/10] Starting project environment...\033[0m" +"${ROLL_DIR}/bin/roll" env up + +# Wait for services to be ready +echo -e "\033[36m[7/10] Waiting for services to be ready...\033[0m" +echo -e "\033[33mChecking service status...\033[0m" + +# Wait for database to be ready +echo -n "Waiting for database... " +timeout=60 +while [ $timeout -gt 0 ]; do + if "${ROLL_DIR}/bin/roll" db connect -e "SELECT 1;" >/dev/null 2>&1; then + echo "✅ Ready" + break + fi + echo -n "." + sleep 2 + timeout=$((timeout-2)) +done + +if [ $timeout -le 0 ]; then + echo "❌ Database not ready after 60 seconds" + exit 1 +fi + +# Wait for search engine to be ready +echo -n "Waiting for search engine... " +timeout=60 +SEARCH_HOST="elasticsearch" +SEARCH_PORT="9200" + +# Determine search engine host based on configuration +# Check environment variables to see which service is actually enabled +if grep -q "^ROLL_OPENSEARCH=1" "${ENV_FILE}" 2>/dev/null; then + SEARCH_HOST="opensearch" + echo -n "(OpenSearch) " +else + echo -n "(Elasticsearch) " +fi + +while [ $timeout -gt 0 ]; do + if "${ROLL_DIR}/bin/roll" cli bash -c "timeout 5 bash -c '/dev/null; then + # Double check with HTTP request if port is open + if "${ROLL_DIR}/bin/roll" cli curl -f -s "http://${SEARCH_HOST}:${SEARCH_PORT}/_cluster/health" >/dev/null 2>&1; then + echo "✅ Ready" + break + fi + fi + echo -n "." + sleep 2 + timeout=$((timeout-2)) +done + +if [ $timeout -le 0 ]; then + echo "❌ Search engine not ready after 60 seconds" + echo "Debug: Checking ${SEARCH_HOST}:${SEARCH_PORT}" + "${ROLL_DIR}/bin/roll" cli bash -c "timeout 5 bash -c '&1 || echo "Port not accessible" + echo "Tip: Make sure ${SEARCH_HOST} service is running with 'roll env up'" + exit 1 +fi + +# Wait for Redis to be ready +echo -n "Waiting for Redis... " +timeout=30 +while [ $timeout -gt 0 ]; do + if "${ROLL_DIR}/bin/roll" redis ping 2>/dev/null | grep -q PONG; then + echo "✅ Ready" + break + fi + echo -n "." + sleep 2 + timeout=$((timeout-2)) +done + +if [ $timeout -le 0 ]; then + echo "❌ Redis not ready after 30 seconds" + exit 1 +fi + +echo -e "\033[32m✅ All services are ready!\033[0m" + +# Drop into shell for setup +echo -e "\033[36m[8/12] Setting up Magento project files...\033[0m" + +# Check if composer global auth is configured +echo -e "\033[33mNote: This process requires Magento Marketplace credentials.\033[0m" +echo -e "\033[33mIf you haven't configured them globally, you'll be prompted during composer install.\033[0m" + +# Meta package for Magento 2.4.6+ +META_PACKAGE="magento/project-community-edition" + +# Create project using composer inside container +"${ROLL_DIR}/bin/roll" cli bash -c " + set -e + + echo 'Creating Magento project with composer...' + composer create-project --repository-url=https://repo.magento.com/ \\ + '${META_PACKAGE}' /tmp/${PROJECT_NAME} '${MAGENTO_VERSION}' + + echo 'Moving files to web root...' + rsync -a /tmp/${PROJECT_NAME}/ /var/www/html/ + rm -rf /tmp/${PROJECT_NAME}/ + + echo 'Setting proper file permissions...' + find /var/www/html -type f -exec chmod 644 {} \\; + find /var/www/html -type d -exec chmod 755 {} \\; + chmod u+x /var/www/html/bin/magento +" + +# Apply Magento 2.4.4 patch for ReflectionUnionType::getName() error +if [[ "${MAGENTO_VERSION}" == "2.4.4"* ]]; then + echo -e "\033[36m[8.5/12] Applying Magento 2.4.4 patches...\033[0m" + echo -e "\033[33m🔧 Detected Magento 2.4.4 - applying ACSD-59280 patch for ReflectionUnionType issue\033[0m" + + "${ROLL_DIR}/bin/roll" cli bash -c " + set -e + + echo 'Installing Quality Patches Tool...' + if ! composer show magento/quality-patches >/dev/null 2>&1; then + composer require magento/quality-patches --no-update + composer update magento/quality-patches --no-dev + fi + + echo 'Checking available patches...' + if vendor/bin/magento-patches status | grep -q 'ACSD-59280'; then + echo 'Applying ACSD-59280 patch for ReflectionUnionType issue...' + vendor/bin/magento-patches apply ACSD-59280 || echo 'Patch may already be applied or not needed' + else + echo 'ACSD-59280 patch not found, may not be needed for this version' + fi + + echo 'Clearing generated code after patching...' + rm -rf generated/metadata generated/code var/generation + " + + echo -e "\033[32m✅ Magento 2.4.4 patches applied successfully\033[0m" +fi + +echo -e "\033[36m[9/12] Installing Magento application...\033[0m" + +# Determine search engine parameters based on version (2.4.6+ only) +echo -e "\033[33mConfiguring search engine parameters...\033[0m" + +# Determine search engine type based on environment configuration +if grep -q "^ROLL_OPENSEARCH=1" "${ENV_FILE}" 2>/dev/null; then + # OpenSearch configuration for Magento 2.4.8+ + OPENSEARCH_VER=$(grep "^OPENSEARCH_VERSION=" "${ENV_FILE}" | cut -d'=' -f2 || echo "2.19") + SEARCH_ENGINE_PARAMS=" + --search-engine=opensearch \\ + --opensearch-host=opensearch \\ + --opensearch-port=9200 \\ + --opensearch-index-prefix=magento2 \\ + --opensearch-enable-auth=0 \\ + --opensearch-timeout=15" + echo -e "\033[33mUsing OpenSearch ${OPENSEARCH_VER} for Magento 2.4.8+\033[0m" +else + # Elasticsearch configuration for Magento 2.4.6-2.4.7 + SEARCH_ENGINE_PARAMS=" + --search-engine=elasticsearch7 \\ + --elasticsearch-host=elasticsearch \\ + --elasticsearch-port=9200 \\ + --elasticsearch-index-prefix=magento2 \\ + --elasticsearch-enable-auth=0 \\ + --elasticsearch-timeout=15" + echo -e "\033[33mUsing Elasticsearch ${ELASTICSEARCH_VERSION}\033[0m" +fi + +# Debug: Show search engine parameters +echo -e "\033[33mSearch engine parameters:\033[0m" +echo "${SEARCH_ENGINE_PARAMS}" + +# Install Magento with fallback mechanism +echo -e "\033[33mAttempting Magento installation with configured search engine...\033[0m" + +# Build the installation command based on search engine type +if grep -q "^ROLL_OPENSEARCH=1" "${ENV_FILE}" 2>/dev/null; then + # OpenSearch installation command + INSTALL_COMMAND="bin/magento setup:install \\ + --backend-frontname=shopmanager \\ + --amqp-host=rabbitmq \\ + --amqp-port=5672 \\ + --amqp-user=guest \\ + --amqp-password=guest \\ + --db-host=db \\ + --db-name=magento \\ + --db-user=magento \\ + --db-password=magento \\ + --search-engine=opensearch \\ + --opensearch-host=opensearch \\ + --opensearch-port=9200 \\ + --opensearch-index-prefix=magento2 \\ + --opensearch-enable-auth=0 \\ + --opensearch-timeout=15 \\ + --http-cache-hosts=varnish:80 \\ + --session-save=redis \\ + --session-save-redis-host=redis \\ + --session-save-redis-port=6379 \\ + --session-save-redis-db=2 \\ + --session-save-redis-max-concurrency=20 \\ + --cache-backend=redis \\ + --cache-backend-redis-server=redis \\ + --cache-backend-redis-db=0 \\ + --cache-backend-redis-port=6379 \\ + --page-cache=redis \\ + --page-cache-redis-server=redis \\ + --page-cache-redis-db=1 \\ + --page-cache-redis-port=6379" +else + # Elasticsearch installation command + INSTALL_COMMAND="bin/magento setup:install \\ + --backend-frontname=shopmanager \\ + --amqp-host=rabbitmq \\ + --amqp-port=5672 \\ + --amqp-user=guest \\ + --amqp-password=guest \\ + --db-host=db \\ + --db-name=magento \\ + --db-user=magento \\ + --db-password=magento \\ + --search-engine=elasticsearch7 \\ + --elasticsearch-host=elasticsearch \\ + --elasticsearch-port=9200 \\ + --elasticsearch-index-prefix=magento2 \\ + --elasticsearch-enable-auth=0 \\ + --elasticsearch-timeout=15 \\ + --http-cache-hosts=varnish:80 \\ + --session-save=redis \\ + --session-save-redis-host=redis \\ + --session-save-redis-port=6379 \\ + --session-save-redis-db=2 \\ + --session-save-redis-max-concurrency=20 \\ + --cache-backend=redis \\ + --cache-backend-redis-server=redis \\ + --cache-backend-redis-db=0 \\ + --cache-backend-redis-port=6379 \\ + --page-cache=redis \\ + --page-cache-redis-server=redis \\ + --page-cache-redis-db=1 \\ + --page-cache-redis-port=6379" +fi + +if ! "${ROLL_DIR}/bin/roll" cli bash -c " + set -e + + echo 'Installing Magento application...' + echo 'Search engine parameters:' + echo '${SEARCH_ENGINE_PARAMS}' + ${INSTALL_COMMAND} +"; then + echo -e "\033[33m⚠️ Primary search engine installation failed, trying fallback to Elasticsearch...\033[0m" + + # Fallback to Elasticsearch 7 + FALLBACK_COMMAND="bin/magento setup:install \\ + --backend-frontname=shopmanager \\ + --amqp-host=rabbitmq \\ + --amqp-port=5672 \\ + --amqp-user=guest \\ + --amqp-password=guest \\ + --db-host=db \\ + --db-name=magento \\ + --db-user=magento \\ + --db-password=magento \\ + --search-engine=elasticsearch7 \\ + --elasticsearch-host=elasticsearch \\ + --elasticsearch-port=9200 \\ + --elasticsearch-index-prefix=magento2 \\ + --elasticsearch-enable-auth=0 \\ + --elasticsearch-timeout=15 \\ + --http-cache-hosts=varnish:80 \\ + --session-save=redis \\ + --session-save-redis-host=redis \\ + --session-save-redis-port=6379 \\ + --session-save-redis-db=2 \\ + --session-save-redis-max-concurrency=20 \\ + --cache-backend=redis \\ + --cache-backend-redis-server=redis \\ + --cache-backend-redis-db=0 \\ + --cache-backend-redis-port=6379 \\ + --page-cache=redis \\ + --page-cache-redis-server=redis \\ + --page-cache-redis-db=1 \\ + --page-cache-redis-port=6379" + + "${ROLL_DIR}/bin/roll" cli bash -c " + set -e + + echo 'Retrying with Elasticsearch 7 fallback...' + ${FALLBACK_COMMAND} + " + + echo -e "\033[32m✅ Installation completed with Elasticsearch fallback\033[0m" + USED_FALLBACK=1 +else + echo -e "\033[32m✅ Installation completed with configured search engine\033[0m" + USED_FALLBACK=0 +fi + +echo -e "\033[36m[10/12] Configuring Magento application...\033[0m" + +# Configure Magento +"${ROLL_DIR}/bin/roll" cli bash -c " + set -e + + echo 'Configuring base URLs...' + bin/magento config:set --lock-env web/unsecure/base_url \\ + \"https://app.${PROJECT_NAME}.test/\" + + bin/magento config:set --lock-env web/secure/base_url \\ + \"https://app.${PROJECT_NAME}.test/\" + + bin/magento config:set --lock-env web/secure/offloader_header X-Forwarded-Proto + bin/magento config:set --lock-env web/secure/use_in_frontend 1 + bin/magento config:set --lock-env web/secure/use_in_adminhtml 1 + bin/magento config:set --lock-env web/seo/use_rewrites 1 + + echo 'Configuring cache settings...' + bin/magento config:set --lock-env system/full_page_cache/caching_application 2 + bin/magento config:set --lock-env system/full_page_cache/ttl 604800 + bin/magento config:set --lock-env catalog/search/enable_eav_indexer 1 + bin/magento config:set --lock-env dev/static/sign 0 + + echo 'Setting developer mode...' + bin/magento deploy:mode:set -s developer + bin/magento cache:disable block_html full_page +" + +# Configure search engine post-installation for OpenSearch fallback scenarios +if [[ "${USED_FALLBACK}" == "1" ]] && grep -q "^ROLL_OPENSEARCH=1" "${ENV_FILE}" 2>/dev/null; then + echo -e "\033[36mInstallation used Elasticsearch fallback, but OpenSearch is configured for runtime...\033[0m" + echo -e "\033[33m📝 Note: You can manually configure OpenSearch later using:\033[0m" + echo -e "\033[33m bin/magento config:set catalog/search/engine opensearch\033[0m" + echo -e "\033[33m bin/magento config:set catalog/search/opensearch_server_hostname opensearch\033[0m" + echo -e "\033[33m bin/magento config:set catalog/search/opensearch_server_port 9200\033[0m" +fi + +echo -e "\033[36m[11/12] Running initial indexing...\033[0m" +"${ROLL_DIR}/bin/roll" cli bash -c " + bin/magento indexer:reindex + bin/magento cache:flush +" + +echo -e "\033[36m[11/12] Creating admin user and configuring 2FA...\033[0m" + +# Generate admin user and 2FA setup for Magento 2.4.6+ (all supported versions require 2FA) +"${ROLL_DIR}/bin/roll" cli bash -c " + set -e + + # Generate admin credentials + ADMIN_PASS=\"\$(pwgen -n1 16)\" + ADMIN_USER=admin + + echo 'Creating admin user...' + bin/magento admin:user:create \\ + --admin-password=\"\${ADMIN_PASS}\" \\ + --admin-user=\"\${ADMIN_USER}\" \\ + --admin-firstname=\"Local\" \\ + --admin-lastname=\"Admin\" \\ + --admin-email=\"\${ADMIN_USER}@example.com\" + + echo \"Admin Username: \${ADMIN_USER}\" + echo \"Admin Password: \${ADMIN_PASS}\" + + # Configure 2FA + echo 'Configuring 2FA...' + TFA_SECRET=\$(python3 -c \"import base64; print(base64.b32encode('\$(pwgen -A1 128)'.encode()).decode().strip('='))\") + OTPAUTH_URL=\$(printf \"otpauth://totp/%s%%3Alocaladmin%%40example.com?issuer=%s&secret=%s\" \\ + \"app.${PROJECT_NAME}.test\" \"app.${PROJECT_NAME}.test\" \"\${TFA_SECRET}\" + ) + + bin/magento config:set --lock-env twofactorauth/general/force_providers google + bin/magento security:tfa:google:set-secret \"\${ADMIN_USER}\" \"\${TFA_SECRET}\" + + echo \"2FA Setup URL: \${OTPAUTH_URL}\" + echo \"2FA Backup Codes:\" + oathtool -s 30 -w 10 --totp --base32 \"\${TFA_SECRET}\" + + # Generate QR code + segno \"\${OTPAUTH_URL}\" -s 4 -o \"pub/media/\${ADMIN_USER}-totp-qr.png\" + QR_URL=\"https://app.${PROJECT_NAME}.test/media/\${ADMIN_USER}-totp-qr.png?t=\$(date +%s)\" + echo \"QR Code URL: \${QR_URL}\" + + # Save credentials to file for user reference + cat > /var/www/html/admin-credentials.txt << EOL +Magento Admin Credentials +======================== +Username: \${ADMIN_USER} +Password: \${ADMIN_PASS} +2FA Setup URL: \${OTPAUTH_URL} +QR Code URL: \${QR_URL} + +Admin Panel: https://app.${PROJECT_NAME}.test/shopmanager/ +Frontend: https://app.${PROJECT_NAME}.test/ + +Generated on: \$(date) +EOL + + echo 'Admin credentials saved to admin-credentials.txt' +" + +echo -e "\033[36m[12/12] Finalizing setup...\033[0m" + +echo -e "\033[32m✅ Magento 2 project '${PROJECT_NAME}' has been successfully created!\033[0m" +echo "" +echo -e "\033[33m🔗 Access URLs:\033[0m" +echo -e " Frontend: https://app.${PROJECT_NAME}.test/" +echo -e " Admin: https://app.${PROJECT_NAME}.test/shopmanager/" +echo -e " RabbitMQ: https://rabbitmq.${PROJECT_NAME}.test/" +echo -e " Elasticsearch: https://elasticsearch.${PROJECT_NAME}.test/" +echo "" +echo -e "\033[33m📁 Project Location:\033[0m" +echo -e " ${TARGET_DIR}" +echo "" +echo -e "\033[33m🔑 Admin Credentials:\033[0m" +echo -e " Check the file: admin-credentials.txt in your project root" +echo "" +echo -e "\033[33m💡 Next Steps:\033[0m" +echo -e " 1. Navigate to your project: cd ${TARGET_DIR}" +echo -e " 2. Access the shell: roll shell" +echo -e " 3. Open your browser to: https://app.${PROJECT_NAME}.test/" + +if [[ "${USED_FALLBACK}" == "1" ]]; then + echo "" + echo -e "\033[33m⚠️ Installation Note:\033[0m" + echo -e " Installation used Elasticsearch fallback due to OpenSearch connectivity issues" + echo -e " OpenSearch is configured in your environment for future use" + echo -e " Check the manual configuration commands shown above to switch to OpenSearch" +fi + +echo "" +echo -e "\033[33m🛑 To destroy this environment:\033[0m" +echo -e " roll env down -v" +echo "" \ No newline at end of file diff --git a/commands/magento2-init.help b/commands/magento2-init.help new file mode 100755 index 0000000..a693fbc --- /dev/null +++ b/commands/magento2-init.help @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +[[ ! ${ROLL_DIR} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!\033[0m" && exit 1 + +ROLL_USAGE=$(cat < [magento_version] [target_directory] + +\033[33mArguments:\033[0m + project_name Name of the Magento 2 project (required) + Should contain only lowercase letters, numbers, and hyphens + Must start and end with a letter or number + + magento_version Magento version to install (optional, default: 2.4.x) + Supports: major.minor.patch and patch versions + Examples: 2.4.x, 2.4.7, 2.4.7-p3, 2.4.6-p2, 2.3.7 + + target_directory Directory to create project in (optional) + Default: current directory + Project will be created in a subdirectory named after the project + +\033[33mDescription:\033[0m + This command scaffolds a complete Magento 2 project from scratch, including: + + • Automatic compatible software version configuration + • Environment initialization with Docker services + • SSL certificate generation + • Magento installation via Composer + • Database setup and configuration + • Redis/Valkey and Elasticsearch/OpenSearch configuration + • Admin user creation with 2FA setup (for Magento 2.4.x) + • Developer mode configuration + +\033[33mExamples:\033[0m + # Create a new project with default Magento version (2.4.x) + roll magento2-init mystore + + # Create a project with specific Magento version + roll magento2-init mystore 2.4.7 + + # Create a project with patch version + roll magento2-init mystore 2.4.7-p3 + + # Create a project in a specific directory + roll magento2-init mystore 2.4.x ~/Sites/ + + # Create a project with Magento 2.3.x (without mandatory 2FA) + roll magento2-init legacystore 2.3.7 + +\033[33mPrerequisites:\033[0m + • RollDev services must be running (roll svc up) + • Magento Marketplace credentials configured globally: + composer global config http-basic.repo.magento.com + +\033[33mPost-Installation:\033[0m + After successful installation, you will have access to: + • Frontend: https://app..test/ + • Admin Panel: https://app..test/shopmanager/ + • Admin credentials in admin-credentials.txt file + • 2FA QR code (for Magento 2.4.x) accessible via web interface + +\033[33mAutomatic Version Configuration:\033[0m + The command automatically configures compatible software versions based on + the Magento version you specify: + • Magento 2.4.8+: PHP 8.3+, MariaDB 11.4, OpenSearch 2.19, Valkey 8 + • Magento 2.4.7: PHP 8.3, MariaDB 10.6+, Elasticsearch 7.17, Redis 7.2 + • Magento 2.4.6: PHP 8.2, MariaDB 10.6, Elasticsearch 7.17, Redis 7.0+ + • Magento 2.4.5: PHP 8.1, MariaDB 10.4, Elasticsearch 7.17, Redis 6.2+ + • Magento 2.3.x: PHP 7.4, MariaDB 10.3, Elasticsearch 7.6, Redis 5.0 + +\033[33mNote:\033[0m + This process may take several minutes depending on your internet connection + and system performance. The command will handle all setup steps automatically. + +EOF +) + +echo -e "${ROLL_USAGE}" \ No newline at end of file From e0c03b692401236412cea7f763321e1a089a2752 Mon Sep 17 00:00:00 2001 From: Rick Bouma Date: Wed, 11 Jun 2025 10:11:35 +0200 Subject: [PATCH 3/5] add extensive documentation for magento2-init command, including a quick reference guide, usage examples, compatibility matrix, and troubleshooting steps --- docs/environments/magento2.md | 76 +++++ docs/index.md | 2 + docs/magento2-init-quick-reference.md | 99 +++++++ docs/magento2-init.md | 385 ++++++++++++++++++++++++++ docs/usage.md | 6 + 5 files changed, 568 insertions(+) create mode 100644 docs/magento2-init-quick-reference.md create mode 100644 docs/magento2-init.md diff --git a/docs/environments/magento2.md b/docs/environments/magento2.md index af4c6d5..27fe8f6 100644 --- a/docs/environments/magento2.md +++ b/docs/environments/magento2.md @@ -1,5 +1,81 @@ # Installing Magento 2 +## Quick Start with `magento2-init` (Recommended) + +RollDev 3.2+ provides an automated `magento2-init` command that handles the complete Magento 2 setup process in a single command. This is the recommended approach for new projects. + +### Basic Usage + +```bash +roll magento2-init [magento_version] +``` + +### Examples + +```bash +# Create project with latest Magento version +roll magento2-init mystore + +# Create project with specific version +roll magento2-init mystore 2.4.7 + +# Create project with patch version +roll magento2-init mystore 2.4.7-p3 + +# Create project with OpenSearch (Magento 2.4.8+) +roll magento2-init mystore 2.4.8 +``` + +### What it Does + +The `magento2-init` command automates all the manual steps listed below: + +1. **Environment Setup**: Creates `.env.roll` with optimized configuration for the specified Magento version +2. **Version Compatibility**: Automatically configures compatible PHP, MariaDB, Elasticsearch/OpenSearch, Redis, RabbitMQ, and Composer versions +3. **SSL Certificate**: Generates and signs SSL certificate for local development +4. **Service Startup**: Starts all required Docker services (database, search, cache, etc.) +5. **Magento Installation**: Downloads and installs Magento via Composer +6. **Database Configuration**: Sets up database, Redis, and search engine connections +7. **Admin User**: Creates admin user with 2FA setup (for Magento 2.4.x) +8. **Developer Mode**: Configures development-optimized settings + +### Software Version Matrix + +The command automatically selects compatible software versions: + +| Magento Version | PHP | MariaDB | Search Engine | Redis | RabbitMQ | Varnish | +|-----------------|-----|---------|---------------|-------|----------|---------| +| 2.4.8+ | 8.3 | 11.4 | OpenSearch 2.19 | Valkey 8 | 4.1 | 7.7 | +| 2.4.7 | 8.3 | 10.6+ | Elasticsearch 7.17 | Redis 7.2 | 3.13 | 7.5+ | +| 2.4.6 | 8.2 | 10.6 | Elasticsearch 7.17 | Redis 7.0+ | 3.9 | 7.1+ | + +### Prerequisites + +- RollDev services running: `roll svc up` +- Magento Marketplace credentials configured globally: + ```bash + composer global config http-basic.repo.magento.com + ``` + +### Post-Installation Access + +After successful installation: + +- **Frontend**: `https://app..test/` +- **Admin Panel**: `https://app..test/shopmanager/` +- **Admin Credentials**: Check `admin-credentials.txt` in project root +- **2FA QR Code**: Available via web interface for easy mobile setup + +### OpenSearch vs Elasticsearch + +For Magento 2.4.8+, the command automatically configures OpenSearch. If OpenSearch setup fails, it automatically falls back to Elasticsearch 7.17 with instructions for manual OpenSearch configuration. + +--- + +## Manual Installation (Alternative) + +If you prefer manual setup or need custom configuration, follow the detailed steps below. + The below example demonstrates the from-scratch setup of the Magento 2 application for local development. A similar process can easily be used to configure an environment of any other type. This assumes that RollDev has been previously started via `roll svc up` as part of the installation procedure. 1. Create a new directory on your host machine at the location of your choice and then jump into the new directory to get started: diff --git a/docs/index.md b/docs/index.md index 7ca8292..d9fc478 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,6 +28,8 @@ caption: Getting Started installing services +magento2-init +magento2-init-quick-reference usage duplicate backup-restore diff --git a/docs/magento2-init-quick-reference.md b/docs/magento2-init-quick-reference.md new file mode 100644 index 0000000..1e8b38c --- /dev/null +++ b/docs/magento2-init-quick-reference.md @@ -0,0 +1,99 @@ +# Magento 2 Init - Quick Reference + +## Basic Commands + +```bash +# Create project with latest version +roll magento2-init mystore + +# Create with specific version +roll magento2-init mystore 2.4.7 + +# Create with patch version +roll magento2-init mystore 2.4.7-p3 + +# Create with OpenSearch (2.4.8+) +roll magento2-init mystore 2.4.8 + +# Create in custom directory +roll magento2-init mystore 2.4.7 ~/Sites/ +``` + +## Prerequisites Checklist + +- [ ] RollDev services running: `roll svc up` +- [ ] Magento credentials configured: + ```bash + composer global config http-basic.repo.magento.com + ``` + +## Post-Installation URLs + +| Service | URL | +|---------|-----| +| Frontend | `https://app..test/` | +| Admin | `https://app..test/shopmanager/` | +| RabbitMQ | `https://rabbitmq..test/` | +| Search | `https://elasticsearch..test/` | + +## Version Matrix (Auto-Selected) + +| Magento | PHP | MariaDB | Search | Redis | RabbitMQ | +|---------|-----|---------|--------|-------|----------| +| 2.4.8+ | 8.3 | 11.4 | OpenSearch 2.19 | Valkey 8 | 4.1 | +| 2.4.7 | 8.3 | 10.6+ | Elasticsearch 7.17 | Redis 7.2 | 3.13 | +| 2.4.6 | 8.2 | 10.6 | Elasticsearch 7.17 | Redis 7.0+ | 3.9 | + +## Common Post-Install Tasks + +```bash +# Enter project directory +cd + +# Access shell +roll shell + +# Check admin credentials +cat admin-credentials.txt + +# Run Magento commands +roll cli bin/magento cache:flush +roll cli bin/magento indexer:reindex +``` + +## Troubleshooting + +```bash +# Check service status +roll env ps + +# View logs +roll env logs --tail 50 + +# Restart services +roll env restart + +# Test connectivity +roll db connect -e "SELECT 1;" +roll redis ping +``` + +## OpenSearch Manual Config (if needed) + +```bash +roll shell +bin/magento config:set catalog/search/engine opensearch +bin/magento config:set catalog/search/opensearch_server_hostname opensearch +bin/magento config:set catalog/search/opensearch_server_port 9200 +bin/magento indexer:reindex catalogsearch_fulltext +``` + +## Help + +```bash +# Command help +roll magento2-init --help + +# Full documentation +https://rolldev.readthedocs.io/magento2-init/ +``` \ No newline at end of file diff --git a/docs/magento2-init.md b/docs/magento2-init.md new file mode 100644 index 0000000..9091452 --- /dev/null +++ b/docs/magento2-init.md @@ -0,0 +1,385 @@ +# Magento 2 Project Initialization + +## Overview + +The `magento2-init` command provides a fully automated way to scaffold new Magento 2 projects from scratch. Introduced in RollDev 3.2, this command eliminates the need for manual setup steps and ensures consistent, optimized project configurations. + +## Quick Start + +```bash +# Create a new Magento 2 project with default settings +roll magento2-init mystore + +# Create with specific Magento version +roll magento2-init mystore 2.4.7-p3 + +# Create in specific directory +roll magento2-init mystore 2.4.8 ~/Sites/ +``` + +## Command Syntax + +```bash +roll magento2-init [magento_version] [target_directory] +``` + +### Parameters + +| Parameter | Required | Description | Default | +|-----------|----------|-------------|---------| +| `project_name` | Yes | Name of the project (lowercase, alphanumeric, hyphens only) | - | +| `magento_version` | No | Magento version to install | `2.4.x` (latest) | +| `target_directory` | No | Directory to create project in | Current directory | + +### Supported Magento Versions + +- **2.4.6+** (minimum supported) +- **2.4.7** and patch versions (`2.4.7-p1`, `2.4.7-p3`, etc.) +- **2.4.8+** with OpenSearch support +- **2.4.x** for latest stable version + +## Automated Setup Process + +The command performs 12 automated steps: + +### 1. Project Directory Creation +- Creates the project directory structure +- Validates project name format + +### 2. Software Version Compatibility +- Automatically determines compatible software versions +- Configures PHP, MariaDB, search engine, Redis, RabbitMQ, Varnish versions + +### 3. Environment Initialization +- Creates `.env.roll` configuration file +- Sets up RollDev environment for Magento 2 + +### 4. Version-Specific Configuration +- Updates environment file with compatible software versions +- Configures OpenSearch for 2.4.8+ or Elasticsearch for older versions +- Sets up Redis/Valkey based on version requirements + +### 5. SSL Certificate Generation +- Creates and signs SSL certificate for `.test` domain +- Enables HTTPS for local development + +### 6. Docker Services Startup +- Starts all required Docker containers +- Database, search engine, Redis, RabbitMQ, Varnish, web server + +### 7. Service Health Checks +- Waits for database connectivity +- Verifies search engine cluster health +- Confirms Redis availability + +### 8. Magento Project Files +- Downloads Magento via Composer +- Uses `magento/project-community-edition` meta-package +- Sets proper file permissions + +### 9. Magento Installation +- Runs `setup:install` with optimized parameters +- Configures database, Redis, search engine connections +- Sets up RabbitMQ for message queues + +### 10. Application Configuration +- Sets base URLs for frontend and admin +- Configures SSL and security settings +- Optimizes cache and search settings + +### 11. Initial Indexing +- Runs all Magento indexers +- Flushes cache for clean start + +### 12. Admin User & 2FA Setup +- Creates admin user with random password +- Configures Two-Factor Authentication (2FA) +- Generates TOTP QR code for mobile authenticator apps + +## Software Compatibility Matrix + +The command automatically configures compatible software versions based on the Magento version: + +### Magento 2.4.8+ +- **PHP**: 8.3 +- **Database**: MariaDB 11.4 +- **Search**: OpenSearch 2.19 (with Elasticsearch 7.17 fallback) +- **Cache**: Valkey 8 (Redis fork) +- **Queue**: RabbitMQ 4.1 +- **HTTP Cache**: Varnish 7.7 +- **Package Manager**: Composer 2 +- **JavaScript**: Node.js 19 + +### Magento 2.4.7 +- **PHP**: 8.3 +- **Database**: MariaDB 10.6+ (10.11 for p6+) +- **Search**: Elasticsearch 7.17 +- **Cache**: Redis 7.2 +- **Queue**: RabbitMQ 3.13 +- **HTTP Cache**: Varnish 7.5+ (7.7 for p6+) +- **Package Manager**: Composer 2 +- **JavaScript**: Node.js 19 + +### Magento 2.4.6 +- **PHP**: 8.2 +- **Database**: MariaDB 10.6 +- **Search**: Elasticsearch 7.17 +- **Cache**: Redis 7.0+ (7.2 for p8+) +- **Queue**: RabbitMQ 3.9 +- **HTTP Cache**: Varnish 7.1+ (7.5 for p8+) +- **Package Manager**: Composer 2 +- **JavaScript**: Node.js 19 + +## OpenSearch Support + +For Magento 2.4.8 and later versions, the command automatically configures OpenSearch as the primary search engine: + +### Automatic Configuration +- Sets `ROLL_OPENSEARCH=1` in environment +- Configures OpenSearch version 2.19 +- Uses `opensearch` hostname for connections + +### Fallback Mechanism +If OpenSearch installation fails: +- Automatically falls back to Elasticsearch 7.17 +- Provides manual configuration instructions +- Maintains full functionality with fallback + +### Manual OpenSearch Configuration +To manually switch to OpenSearch after installation: + +```bash +roll shell +bin/magento config:set catalog/search/engine opensearch +bin/magento config:set catalog/search/opensearch_server_hostname opensearch +bin/magento config:set catalog/search/opensearch_server_port 9200 +bin/magento indexer:reindex catalogsearch_fulltext +``` + +## Prerequisites + +### Required Setup +1. **RollDev Services**: Must be running (`roll svc up`) +2. **Magento Marketplace Credentials**: Configure globally: + ```bash + composer global config http-basic.repo.magento.com + ``` + +### Magento Marketplace Authentication +To obtain credentials: +1. Visit [Magento Marketplace](https://marketplace.magento.com/) +2. Go to My Profile → Access Keys +3. Generate new Access Key +4. Use **Public Key** as username and **Private Key** as password + +## Post-Installation + +### Access URLs +After successful installation, your project will be available at: + +- **Frontend**: `https://app..test/` +- **Admin Panel**: `https://app..test/shopmanager/` +- **RabbitMQ Management**: `https://rabbitmq..test/` +- **Elasticsearch/OpenSearch**: `https://elasticsearch..test/` or `https://opensearch..test/` + +### Admin Credentials +Check the `admin-credentials.txt` file in your project root for: +- Admin username and password +- 2FA setup URL +- QR code URL for mobile authenticator apps +- Backup codes for emergency access + +### 2FA Setup +1. Open the QR code URL in your browser +2. Scan with authenticator app (Google Authenticator, Authy, etc.) +3. Use generated codes to log into admin panel + +## Examples + +### Basic Project Creation +```bash +# Create with latest Magento version +roll magento2-init mystore +cd mystore +``` + +### Specific Version +```bash +# Create with Magento 2.4.7 +roll magento2-init ecommerce-site 2.4.7 +cd ecommerce-site +``` + +### Patch Version +```bash +# Create with specific patch version +roll magento2-init secure-shop 2.4.7-p3 +cd secure-shop +``` + +### Custom Location +```bash +# Create in specific directory +roll magento2-init client-project 2.4.8 ~/Sites/clients/ +cd ~/Sites/clients/client-project +``` + +### OpenSearch Project +```bash +# Create with OpenSearch (2.4.8+) +roll magento2-init modern-store 2.4.8 +cd modern-store +``` + +## Troubleshooting + +### Common Issues + +#### Composer Authentication +**Error**: `Could not authenticate package information` +**Solution**: Configure Magento Marketplace credentials: +```bash +composer global config http-basic.repo.magento.com +``` + +#### Service Connectivity +**Error**: `Database/Redis/Search engine not ready` +**Solution**: Ensure services are running: +```bash +roll env up +roll env logs +``` + +#### Permission Issues +**Error**: `Permission denied` during installation +**Solution**: Check Docker permissions and volume mounts: +```bash +roll env restart +``` + +#### Search Engine Fallback +**Warning**: `Installation used Elasticsearch fallback` +**Info**: This is normal for OpenSearch configurations that fail. The project will work with Elasticsearch. You can manually configure OpenSearch later using the provided commands. + +### Debug Commands + +Check service status: +```bash +roll env ps +roll env logs --tail 50 +``` + +Verify database connectivity: +```bash +roll db connect -e "SELECT 1;" +``` + +Check search engine health: +```bash +roll cli curl -f "http://elasticsearch:9200/_cluster/health" +roll cli curl -f "http://opensearch:9200/_cluster/health" +``` + +Test Redis connection: +```bash +roll redis ping +``` + +## Environment Management + +### Starting/Stopping +```bash +# Start environment +roll env up + +# Stop environment +roll env stop + +# Restart environment +roll env restart + +# Remove environment completely +roll env down -v +``` + +### Shell Access +```bash +# Enter project shell +roll shell + +# Run single command +roll cli bin/magento cache:flush +``` + +### Database Operations +```bash +# Connect to database +roll db connect + +# Import database dump +pv dump.sql.gz | gunzip -c | roll db import + +# Export database +roll db export > backup.sql +``` + +## Performance Tips + +### Development Mode +The installation automatically sets developer mode for optimal development: +- Disables block and page cache +- Enables file-based generation +- Shows detailed error messages + +### Production Simulation +To test production-like performance: +```bash +roll shell +bin/magento deploy:mode:set production +bin/magento static:content:deploy +bin/magento indexer:reindex +``` + +### Cache Management +```bash +# Flush all caches +roll cli bin/magento cache:flush + +# Enable/disable specific caches +roll cli bin/magento cache:enable block_html +roll cli bin/magento cache:disable full_page +``` + +## Advanced Configuration + +### Custom Environment Variables +Modify `.env.roll` after installation for custom configurations: + +```bash +# Enable additional services +ROLL_BLACKFIRE=1 +ROLL_MAGEPACK=1 +ROLL_SELENIUM=1 + +# Adjust service versions +PHP_VERSION=8.4 +ELASTICSEARCH_VERSION=8.0 +``` + +### Multi-Store Setup +Configure additional domains after installation: +```bash +roll sign-certificate store2.test +# Configure stores in Magento admin +``` + +### Custom SSL Certificates +```bash +# Sign additional certificates +roll sign-certificate api.myproject.test +roll sign-certificate admin.myproject.test +``` + +--- + +*For more information about RollDev environments and customization, see the [Environment Types](environments/types.md) and [Customization](environments/customizing.md) documentation.* \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md index 7084c84..84edd6b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -2,6 +2,12 @@ ## Common Commands +### Project Initialization + +Create a new Magento 2 project (automated setup): + + roll magento2-init myproject 2.4.7 + Launch a shell session within the project environment's `php-fpm` container: roll shell From 6cdd27925772fca053574ffca3088172bd234f4c Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Jun 2025 08:12:01 +0000 Subject: [PATCH 4/5] Tagged 3.2 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 9e11b32..a3ec5a4 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.3.1 +3.2 From 76299c2296b25f0da7d6720114f0045f235ad7d0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 11 Jun 2025 08:15:37 +0000 Subject: [PATCH 5/5] Tagged 0.3.2 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index a3ec5a4..d15723f 100644 --- a/version +++ b/version @@ -1 +1 @@ -3.2 +0.3.2