104 lines
3.8 KiB
Bash
Executable File
104 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Aplica migrations do ConectaSUS para uma lista explicita de municipios.
|
|
#
|
|
# ./migrate.sh <ambiente> <tag> <municipio[,municipio...]>
|
|
#
|
|
# A migration roda em um container descartavel da imagem informada. Assim ela
|
|
# nao depende de qual versao esta no ar e usa os mesmos .env,
|
|
# connections.json e storage montados no host do ambiente.
|
|
|
|
set -euo pipefail
|
|
|
|
AMBIENTE="${1:-}"
|
|
TAG="${2:-}"
|
|
MUNICIPIOS_CSV="${3:-}"
|
|
REGISTRY="${REGISTRY:-192.168.0.41:3001}"
|
|
IMAGE_NAME="${IMAGE_NAME:-rkm/conectasus-api}"
|
|
|
|
AQUI="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
log() { echo "[migrate] $*"; }
|
|
fail() { echo "[migrate][ERRO] $*" >&2; exit 1; }
|
|
|
|
[ -n "${AMBIENTE}" ] || fail "uso: $0 <ambiente> <tag> <municipio[,municipio...]>"
|
|
[ -n "${TAG}" ] || fail "uso: $0 <ambiente> <tag> <municipio[,municipio...]>"
|
|
[ -n "${MUNICIPIOS_CSV}" ] || fail "informe ao menos um municipio"
|
|
|
|
ENV_FILE="${AQUI}/${AMBIENTE}.env"
|
|
[ -f "${ENV_FILE}" ] || fail "ambiente desconhecido: ${AMBIENTE} (esperado ${ENV_FILE})"
|
|
|
|
# shellcheck disable=SC1090
|
|
set -a; . "${ENV_FILE}"; set +a
|
|
|
|
if grep -q 'TROCAR' "${ENV_FILE}"; then
|
|
fail "${ENV_FILE} ainda tem valores de gabarito (TROCAR)."
|
|
fi
|
|
|
|
for v in CONFIG_DIR; do
|
|
[ -n "${!v:-}" ] || fail "${v} nao definido em ${ENV_FILE}"
|
|
done
|
|
|
|
IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
|
|
|
|
# Nomes de conexao do Laravel nao devem conter espacos nem caracteres que
|
|
# possam alterar a linha de comando. A lista e propositalmente explicita:
|
|
# conexoes tecnicas (por exemplo, sigtap) nao devem receber migrations por
|
|
# acidente.
|
|
IFS=',' read -r -a MUNICIPIOS_BRUTOS <<< "${MUNICIPIOS_CSV}"
|
|
declare -a MUNICIPIOS=()
|
|
declare -A VISTOS=()
|
|
for bruto in "${MUNICIPIOS_BRUTOS[@]}"; do
|
|
municipio="$(echo "${bruto}" | tr -d '[:space:]')"
|
|
[ -n "${municipio}" ] || fail "ha um municipio vazio na lista: ${MUNICIPIOS_CSV}"
|
|
[[ "${municipio}" =~ ^[A-Za-z0-9_-]+$ ]] || fail "nome de municipio invalido: ${municipio}"
|
|
[ -z "${VISTOS[${municipio}]:-}" ] || fail "municipio repetido na lista: ${municipio}"
|
|
VISTOS["${municipio}"]=1
|
|
MUNICIPIOS+=("${municipio}")
|
|
done
|
|
|
|
log "ambiente : ${AMBIENTE}"
|
|
log "imagem : ${IMAGE}"
|
|
log "municipios: ${MUNICIPIOS[*]}"
|
|
|
|
log "puxando ${IMAGE}"
|
|
docker pull "${IMAGE}" >/dev/null || fail "pull falhou (registry acessivel? credencial presente?)"
|
|
|
|
# --mount valida as fontes no host do Docker. Isso e essencial quando o job
|
|
# roda em container do act_runner, cujo filesystem nao contem CONFIG_DIR.
|
|
MOUNTS=(
|
|
--mount "type=bind,src=${CONFIG_DIR}/.env,dst=/var/www/api/.env,readonly"
|
|
--mount "type=bind,src=${CONFIG_DIR}/connections.json,dst=/var/www/api/connections.json,readonly"
|
|
--mount "type=bind,src=${CONFIG_DIR}/storage,dst=/var/www/api/storage"
|
|
)
|
|
|
|
PHP_RUN=(docker run --rm "${MOUNTS[@]}" --workdir /var/www/api --entrypoint php "${IMAGE}")
|
|
|
|
# Confere o JSON e todas as conexoes antes de alterar qualquer banco. Nao lista
|
|
# nem imprime o conteudo do arquivo, que pode conter credenciais.
|
|
for municipio in "${MUNICIPIOS[@]}"; do
|
|
if ! "${PHP_RUN[@]}" -r '
|
|
$connections = json_decode(file_get_contents("connections.json"), true);
|
|
if (!is_array($connections) || !array_key_exists($argv[1], $connections)) {
|
|
fwrite(STDERR, "conexao nao encontrada no connections.json: " . $argv[1] . PHP_EOL);
|
|
exit(1);
|
|
}
|
|
' "${municipio}"; then
|
|
fail "validacao da conexao falhou; nenhum banco recebeu migration"
|
|
fi
|
|
done
|
|
|
|
MIGRATE_RUN=("${PHP_RUN[@]}")
|
|
if [ -n "${NETWORK:-}" ]; then
|
|
MIGRATE_RUN=(docker run --rm --network "${NETWORK}" "${MOUNTS[@]}" --workdir /var/www/api --entrypoint php "${IMAGE}")
|
|
fi
|
|
|
|
total="${#MUNICIPIOS[@]}"
|
|
for i in "${!MUNICIPIOS[@]}"; do
|
|
municipio="${MUNICIPIOS[${i}]}"
|
|
log "[$((i + 1))/${total}] aplicando migrations em ${municipio}"
|
|
"${MIGRATE_RUN[@]}" artisan migrate --database="${municipio}" --force
|
|
done
|
|
|
|
log "migrations concluidas para ${total} municipio(s)"
|