diff --git a/app.last_run.txt b/app.last_run.txt deleted file mode 100644 index 1b2374d..0000000 --- a/app.last_run.txt +++ /dev/null @@ -1 +0,0 @@ -2025-11-30 18:28:15 \ No newline at end of file diff --git a/scripts/build-factuges-sync.sh b/scripts/build-factuges-sync.sh index 3a8e367..e39f686 100755 --- a/scripts/build-factuges-sync.sh +++ b/scripts/build-factuges-sync.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -SCRIPT_VERSION="2.0.2" +SCRIPT_VERSION="2.3" # ================================================ # FACTUGES SYNC - Docker Build Script (Simplificado) @@ -21,6 +21,17 @@ COMPANY="$1" LOAD=false [[ "${2:-}" == "--load" ]] && LOAD=true +SSH_USER="rodax" +SSH_HOST="vps-2.rodax-software.com" +SSH_PORT="49152" + +# Override por compañía específica +if [[ "$COMPANY" == "rodax" ]]; then + SSH_USER="rodax" + SSH_HOST="factuges.rodax-software.local" + SSH_PORT="22" +fi + # ---------- 2. Directorios ---------- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(realpath "${SCRIPT_DIR}/..")" @@ -38,10 +49,6 @@ IMAGE_VERSION=$(sed -n 's/^version[[:space:]]*=[[:space:]]*\(.*\)$/\1/p' \ "$PROJECT_DIR/setup.cfg" | head -n1) IMAGE_VERSION="${IMAGE_VERSION:-0.0.0}" -IMAGE_NAME="factuges-sync" -TAG_VERSION="${IMAGE_NAME}:${COMPANY}-${IMAGE_VERSION}" -TAG_LATEST="${IMAGE_NAME}:${COMPANY}-latest" - echo "" echo "-------------------------------------------------------" echo " FACTUGES SYNC Build Script v${SCRIPT_VERSION}" @@ -49,31 +56,54 @@ echo " Compañía: ${COMPANY}" echo " Versión: ${IMAGE_VERSION}" echo " Fecha: ${DATE}" echo " Carga: ${LOAD}" +echo " Modos: factuges + verifactu" echo "-------------------------------------------------------" echo "" -# ---------- 4. Build único ---------- -echo "📦 Construyendo imagen Docker..." -#docker build --no-cache \ -docker build \ - -t "${TAG_VERSION}" \ - -t "${TAG_LATEST}" \ - --build-arg COMPANY="${COMPANY}" \ - -f "${PROJECT_DIR}/Dockerfile" "${PROJECT_DIR}" +# ---------- 4. Función build ---------- +build_image() { + local MODE="$1" # factuges | verifactu + local IMAGE_NAME="factuges-sync-${MODE}" -echo "✅ Imagen construida: ${TAG_VERSION}" + local TAG_VERSION="${IMAGE_NAME}:${COMPANY}-${IMAGE_VERSION}" + local TAG_LATEST="${IMAGE_NAME}:${COMPANY}-latest" -# ---------- 5. Save tar ---------- -TAR_V="${OUT_DIR}/${IMAGE_NAME}-${COMPANY}-v${IMAGE_VERSION}-${DATE}.tar" -TAR_LATEST="${OUT_DIR}/${IMAGE_NAME}-${COMPANY}-latest.tar" + echo "📦 Construyendo imagen Docker (${MODE})..." -docker save -o "${TAR_V}" "${TAG_VERSION}" "${TAG_LATEST}" -cp -f "${TAR_V}" "${TAR_LATEST}" + docker build --no-cache \ + -t "${TAG_VERSION}" \ + -t "${TAG_LATEST}" \ + --build-arg COMPANY="${COMPANY}" \ + -f "${PROJECT_DIR}/Dockerfile.${MODE}" "${PROJECT_DIR}" + + echo "✅ Imagen construida: ${TAG_VERSION}" + + local TAR_V="${OUT_DIR}/${IMAGE_NAME}-${COMPANY}-v${IMAGE_VERSION}-${DATE}.tar" + local TAR_LATEST="${OUT_DIR}/${IMAGE_NAME}-${COMPANY}-latest.tar" + + docker save -o "${TAR_V}" "${TAG_VERSION}" "${TAG_LATEST}" + cp -f "${TAR_V}" "${TAR_LATEST}" + + echo "📦 Imagen guardada:" + echo " - ${TAR_V}" + echo " - ${TAR_LATEST}" + + # Devuelve SOLO datos (para uso posterior) + echo "${TAR_V}|${TAR_LATEST}" +} + + +# ---------- 5. Builds ---------- +FACTUGES_OUT=$(build_image "factuges") +FACTUGES_TAR_V="${FACTUGES_OUT%%|*}" +FACTUGES_TAR_LATEST="${FACTUGES_OUT##*|}" + +VERIFACTU_OUT=$(build_image "verifactu") +VERIFACTU_TAR_V="${VERIFACTU_OUT%%|*}" +VERIFACTU_TAR_LATEST="${VERIFACTU_OUT##*|}" +VERIFACTU_TAR_LATEST=$(build_image "verifactu" | sed -n '2p') -echo "📦 Imagen guardada:" -echo " - ${TAR_V}" -echo " - ${TAR_LATEST}" # ---------- 6. Manifest ---------- MANIFEST_FILE="${OUT_DIR}/manifest-${IMAGE_VERSION}-${DATE}.json" @@ -83,9 +113,13 @@ cat > "${MANIFEST_FILE}" </dev/null 2>&1; then + echo "❌ Docker no está instalado o no está en PATH" + exit 1 +fi +echo "✔ Docker disponible" + +# ---- 2. companies.list existe ---- +if [[ ! -f "$COMPANIES_FILE" ]]; then + echo "❌ No existe ${COMPANIES_FILE}" + exit 1 +fi +echo "✔ companies.list encontrado" + +# ---- 3. Validar imágenes por compañía ---- +ERRORS=0 + +while read -r COMPANY; do + [[ -z "$COMPANY" ]] && continue + [[ "$COMPANY" == \#* ]] && continue + + echo "" + echo "→ Comprobando compañía: ${COMPANY}" + + for MODE in factuges verifactu; do + IMAGE="factuges-sync-${MODE}:${COMPANY}-latest" + if docker image inspect "$IMAGE" >/dev/null 2>&1; then + echo " ✔ Imagen encontrada: ${IMAGE}" + else + echo " ❌ Imagen NO encontrada: ${IMAGE}" + ERRORS=$((ERRORS + 1)) + fi + done + +done < "$COMPANIES_FILE" + +# ---- 4. Resultado final ---- +if [[ "$ERRORS" -gt 0 ]]; then + echo "" + echo "❌ Hay ${ERRORS} errores. No es seguro instalar cron." + exit 1 +fi + +echo "" +echo "---------------------------------------------" +echo "✅ Todas las comprobaciones OK" +echo "👉 Puedes ejecutar deploy-cron.sh con seguridad" +echo "🧩 Script version: ${SCRIPT_VERSION}" +echo "---------------------------------------------" +echo "" + diff --git a/scripts/cronjob b/scripts/cronjob deleted file mode 100644 index 68fbae7..0000000 --- a/scripts/cronjob +++ /dev/null @@ -1,13 +0,0 @@ -# ===== FACTUGES SYNC JOBS ===== - -# Sincronización FactuGES → cada 5 minutos -*/5 * * * * docker run --rm \ - -e ENV=production \ - factuges-sync-factuges:acme-latest \ - >> /var/log/factuges-sync/factuges.log 2>&1 - -# Sincronización Verifactu → cada 7 minutos -*/7 * * * * docker run --rm \ - -e ENV=production \ - factuges-sync-verifactu:acme-latest \ - >> /var/log/factuges-sync/verifactu.log 2>&1 diff --git a/scripts/deploy-cron.sh b/scripts/deploy-cron.sh index b0304cf..c62bef4 100755 --- a/scripts/deploy-cron.sh +++ b/scripts/deploy-cron.sh @@ -1,45 +1,77 @@ #!/usr/bin/env bash set -euo pipefail +SCRIPT_VERSION="1.0" + # ================================================ -# FACTUGES SYNC - Deploy cron jobs +# FACTUGES SYNC - Deploy cron jobs (MULTI COMPANY) # ----------------------------------------------- # Este script: -# - Crea /var/log/factuges-sync -# - Instala los cron jobs de producción -# - Mantiene los cron jobs idempotentes +# - Lee la lista de compañías desde companies.list +# - Genera automáticamente los CRON de cada compañía +# - Instala un CRON único con todas las compañías +# - Crea directorios de logs por compañía # ================================================ -COMPANY="${1:-acme}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +COMPANIES_FILE="${SCRIPT_DIR}/companies.list" -CRON_FILE="/tmp/factuges-sync-cron-${COMPANY}.txt" +if [[ ! -f "$COMPANIES_FILE" ]]; then + echo "❌ ERROR: No existe ${COMPANIES_FILE}" + exit 1 +fi -echo "📄 Generando cron file temporal: ${CRON_FILE}" +CRON_FILE="/tmp/factuges-sync-cron-all.txt" -mkdir -p /var/log/factuges-sync +echo "" +echo "-------------------------------------------------------" +echo " FACTUGES SYNC - Deploy cron jobs (MULTI COMPANY) v${SCRIPT_VERSION}" +echo "-------------------------------------------------------" +echo "" -cat > "$CRON_FILE" < "$CRON_FILE" + +while read -r COMPANY; do + [[ -z "$COMPANY" ]] && continue # saltar líneas vacías + [[ "$COMPANY" == \#* ]] && continue # saltar comentarios + + LOG_DIR="/var/log/factuges-sync/${COMPANY}" + + echo "→ Añadiendo compañía: ${COMPANY}" + echo " Logs en: ${LOG_DIR}" + + # Crear directorio de logs por compañía + sudo mkdir -p "$LOG_DIR" + + cat >> "$CRON_FILE" <> /var/log/factuges-sync/factuges.log 2>&1 + >> ${LOG_DIR}/factuges.log 2>&1 -# Sincronización Verifactu → cada 7 minutos +# Sincronización Verifactu (cada 7 min) */7 * * * * docker run --rm \ - -e ENV=production \ + -e ENV=prod \ factuges-sync-verifactu:${COMPANY}-latest \ - >> /var/log/factuges-sync/verifactu.log 2>&1 + >> ${LOG_DIR}/verifactu.log 2>&1 + EOF -echo "📥 Instalando cron jobs del sistema..." +done < "$COMPANIES_FILE" -crontab "$CRON_FILE" +echo "📥 Instalando CRON final..." +sudo crontab "$CRON_FILE" +echo "" echo "---------------------------------------------" -echo "✔ Cron jobs instalados correctamente" -echo "✔ Logs → /var/log/factuges-sync/" -echo "✔ Puedes comprobar con: crontab -l" +echo "🎯 CRON multi-compañía instalado correctamente" +echo "✔ companies.list leído desde: ${COMPANIES_FILE}" +echo "✔ Ver crontab: sudo crontab -l" +echo "✔ Logs: /var/log/factuges-sync//" +echo "🧩 Script version: ${SCRIPT_VERSION}" echo "---------------------------------------------" +echo "" diff --git a/scripts/docker-compose.rodax.yml b/scripts/docker-compose.rodax.yml new file mode 100644 index 0000000..3f3f953 --- /dev/null +++ b/scripts/docker-compose.rodax.yml @@ -0,0 +1,90 @@ +services: + + factuges_sync: + image: "factuges-sync-factuges:rodax-latest" + container_name: "factuges_rodax_sync_factuges" + restart: "no" + environment: + ENV: "production" + LOCAL_TZ: "Europe/Madrid" + STATE_PATH: "${STATE_PATH}" + + FACTUGES_HOST: "${FACTUGES_HOST}" + FACTUGES_PORT: "${FACTUGES_PORT}" + FACTUGES_DATABASE: "${FACTUGES_DATABASE}" + FACTUGES_USER: "${FACTUGES_USER}" + FACTUGES_PASSWORD: "${FACTUGES_PASSWORD}" + + FWEB_MYSQL_HOST: "db" + FWEB_MYSQL_PORT: "${DB_PORT}" + FWEB_MYSQL_DATABASE: "${DB_NAME}" + FWEB_MYSQL_USER: "${DB_USER}" + FWEB_MYSQL_PASSWORD: "${DB_PASS}" + + CTE_COMPANY_ID: "${CTE_COMPANY_ID}" + CTE_SERIE: "${CTE_SERIE}" + CTE_STATUS_INVOICE: "${CTE_STATUS_INVOICE}" + CTE_IS_PROFORMA: "${CTE_IS_PROFORMA}" + CTE_STATUS_VERIFACTU: "${CTE_STATUS_VERIFACTU}" + CTE_LANGUAGE_CODE: "${CTE_LANGUAGE_CODE}" + CTE_COUNTRY_CODE: "${CTE_COUNTRY_CODE}" + CTE_IS_COMPANY: "${CTE_IS_COMPANY}" + CTE_SYNC_RESULT_OK: "${CTE_SYNC_RESULT_OK}" + CTE_SYNC_RESULT_FAIL: "${CTE_SYNC_RESULT_FAIL}" + + VERIFACTU_API_KEY: "${VERIFACTU_API_KEY}" + VERIFACTU_BASE_URL: "${VERIFACTU_BASE_URL}" + VERIFACTU_NIFS_API_KEY: "${VERIFACTU_NIFS_API_KEY}" + depends_on: + db: + condition: service_healthy + networks: + - internal + - edge + volumes: + - ./volumes/db_sync:/app/rodax + + + verifactu_sync: + image: "factuges-sync-verifactu:rodax-latest" + container_name: "factuges_rodax_sync_verifactu" + restart: "no" + environment: + ENV: "production" + LOCAL_TZ: "Europe/Madrid" + STATE_PATH: "${STATE_PATH}" + + FACTUGES_HOST: "${FACTUGES_HOST}" + FACTUGES_PORT: "${FACTUGES_PORT}" + FACTUGES_DATABASE: "${FACTUGES_DATABASE}" + FACTUGES_USER: "${FACTUGES_USER}" + FACTUGES_PASSWORD: "${FACTUGES_PASSWORD}" + + FWEB_MYSQL_HOST: "db" + FWEB_MYSQL_PORT: "${DB_PORT}" + FWEB_MYSQL_DATABASE: "${DB_NAME}" + FWEB_MYSQL_USER: "${DB_USER}" + FWEB_MYSQL_PASSWORD: "${DB_PASS}" + + CTE_COMPANY_ID: "${CTE_COMPANY_ID}" + CTE_SERIE: "${CTE_SERIE}" + CTE_STATUS_INVOICE: "${CTE_STATUS_INVOICE}" + CTE_IS_PROFORMA: "${CTE_IS_PROFORMA}" + CTE_STATUS_VERIFACTU: "${CTE_STATUS_VERIFACTU}" + CTE_LANGUAGE_CODE: "${CTE_LANGUAGE_CODE}" + CTE_COUNTRY_CODE: "${CTE_COUNTRY_CODE}" + CTE_IS_COMPANY: "${CTE_IS_COMPANY}" + CTE_SYNC_RESULT_OK: "${CTE_SYNC_RESULT_OK}" + CTE_SYNC_RESULT_FAIL: "${CTE_SYNC_RESULT_FAIL}" + + VERIFACTU_API_KEY: "${VERIFACTU_API_KEY}" + VERIFACTU_BASE_URL: "${VERIFACTU_BASE_URL}" + VERIFACTU_NIFS_API_KEY: "${VERIFACTU_NIFS_API_KEY}" + depends_on: + db: + condition: service_healthy + networks: + - internal + - edge + volumes: + - ./volumes/db_sync:/app/rodax \ No newline at end of file diff --git a/scripts/stack.rodax.env b/scripts/stack.rodax.env index eec022e..aacf262 100644 --- a/scripts/stack.rodax.env +++ b/scripts/stack.rodax.env @@ -27,6 +27,7 @@ CTE_IS_COMPANY = 1 CTE_SYNC_RESULT_OK = 1 CTE_SYNC_RESULT_FAIL = 2 -VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI= +#VERIFACTU_API_KEY = vf_test_C03HL2F0X5OXSDRunjNFoMxD4IrRfK3kCC8PfcvCENI= +#VERIFACTU_API_KEY = vf_prod_yfjonNPv2E4Fij+5J0hct0zCgUeFYT2dZzb23UZlM+Q= VERIFACTU_BASE_URL = https://api.verifacti.com/ VERIFACTU_NIFS_API_KEY = vfn_osYpNdqSzAdTAHpazXG2anz4F3o0gfbSb5FFrCBZcno= diff --git a/scripts/undeploy-cron.sh b/scripts/undeploy-cron.sh new file mode 100644 index 0000000..4df114f --- /dev/null +++ b/scripts/undeploy-cron.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_VERSION="1.0" + +# ================================================ +# FACTUGES SYNC - Undeploy cron jobs +# ----------------------------------------------- +# Este script: +# - Elimina el crontab instalado por deploy-cron.sh +# - NO borra logs +# - NO toca imágenes Docker +# - Seguro de ejecutar varias veces +# ================================================ + +TMP_CRON="/tmp/current-cron.txt" +TMP_FILTERED="/tmp/filtered-cron.txt" + +echo "" +echo "-------------------------------------------------------" +echo " FACTUGES SYNC - Undeploy cron jobs v${SCRIPT_VERSION}" +echo "-------------------------------------------------------" +echo "" + +echo "🧹 Eliminando cron jobs de FactuGES Sync..." + +# Guardar cron actual (si existe) +crontab -l > "$TMP_CRON" 2>/dev/null || true + +# Eliminar bloques FACTUGES SYNC +grep -v "FACTUGES SYNC JOBS" "$TMP_CRON" \ + | grep -v "factuges-sync-factuges" \ + | grep -v "factuges-sync-verifactu" \ + > "$TM + +echo "" +echo "---------------------------------------------" +echo "🎯 Terminado correctamente +echo "🧩 Script version: ${SCRIPT_VERSION}" +echo "---------------------------------------------" +echo "" diff --git a/setup.cfg b/setup.cfg index 4527925..1cb9cf5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = factuges-sync -version = 0.1.5 +version = 0.1.6 description = ETL job to sync data from legacy DB to MariaDB author = Rodax Software author_email = info@rodax-software.com