From e615c113f887672411a291ec141431d2707ebde0 Mon Sep 17 00:00:00 2001 From: Christian Tosta Date: Fri, 30 May 2025 13:14:06 -0300 Subject: [PATCH] Initial import --- .env | 2 + builtin/cli-minimal.bash | 55 ++ sig-installer | 859 ++++++++++++++++++++++++++++++++ sig-installer-dev | 849 +++++++++++++++++++++++++++++++ tests/00-create-container.sh | 4 + tests/01-install-requires.sh | 17 + tests/90-run-container-shell.sh | 3 + tests/90-run-sig-installer.sh | 3 + tests/99-destroy-container.sh | 3 + tests/compose.yml | 11 + 10 files changed, 1806 insertions(+) create mode 100644 .env create mode 100755 builtin/cli-minimal.bash create mode 100644 sig-installer create mode 100755 sig-installer-dev create mode 100644 tests/00-create-container.sh create mode 100755 tests/01-install-requires.sh create mode 100644 tests/90-run-container-shell.sh create mode 100644 tests/90-run-sig-installer.sh create mode 100644 tests/99-destroy-container.sh create mode 100644 tests/compose.yml diff --git a/.env b/.env new file mode 100644 index 0000000..2d3c7dc --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +COMPOSE_FILE=tests/compose.yml +COMPOSE_BAKE=true diff --git a/builtin/cli-minimal.bash b/builtin/cli-minimal.bash new file mode 100755 index 0000000..7a1a2b1 --- /dev/null +++ b/builtin/cli-minimal.bash @@ -0,0 +1,55 @@ +export NO_FMT="\033[0m" +export F_BOLD="\033[1m" + +export C_NONE="\033[0m" +export C_RED="\033[38;5;9m" +export C_BLUE="\033[38;5;12m" +export C_GREEN="\033[38;5;2m" +export C_ORANGE="\033[38;5;208m" +export C_GOLD="\033[38;5;220m" +export C_PURPLE="\033[38;5;5m" + +export S_INFO="${C_BLUE}\u2691 [info] ${NO_FMT} " +export S_SUCCESS="${C_GREEN}\u2691 [success] ${NO_FMT}\u2713 " +export S_DEBUG="${C_PURPLE}\u2691 [debug]${NO_FMT} " +export S_WARN="${C_ORANGE}\u2691 [warning] ${NO_FMT} " +export S_ERROR="${C_RED}\u2691 [error] ${NO_FMT}\u2715 " + +export U_ITEM="\u2192" + +export COLS="$(( $(tput cols) - 1 ))" + +cli.section() { + __section.header() { + __section.title() { + printf $"${@:1:1}" \ + $(echo -ne ${F_BOLD}${C_BLUE}${@:2:1}${NO_FMT}) \ + $(echo -ne ${C_ORANGE}${@:3}${NO_FMT}) + } + __section.title.underline() { + for i in $(seq 1 ${COLS}); do \ + printf "%s" $(echo -ne "\u2581"); \ + done + } + __section.title "${@}" + __section.title.underline + } + __section.content() { + printf "%2s\n" + printf "%s" "${@}" | fold -sw ${COLS} + } + __section.footer() { + __section.footer.line() { + [ -z "${1:-}" ] && printf "%s\n" + for i in $(seq 1 ${COLS}); do \ + printf "%s" $(echo -ne "\u2504${NO_FMT}"); \ + done && \ + [ -z "${1:-}" ] && printf "%2s\n" + } + __section.footer.line + } + __section.header "${@:1:3}" + __section.content "${@:4}" + __section.footer +} +cli.section "${@}" diff --git a/sig-installer b/sig-installer new file mode 100644 index 0000000..85a0123 --- /dev/null +++ b/sig-installer @@ -0,0 +1,859 @@ +#!/bin/bash + +set -euo pipefail +self=$(basename ${0}) +self=${self/.*bash} +version=2505.6 + +# == Funções Gerais ============================================================================== # + +function self.check_essential { + # We need at least some programs installed + local _essential=" \ + libarchive-tools:bsdtar \ + curl:curl \ + git-core:git \ + iproute2:ip \ + iputils-ping:ping \ + jq:jq \ + python3-yaml:jq \ + locales:locale-gen \ + openssh-server:sshd \ + sudo:sudo \ + unzip:unzip \ + tzdata:tzconfig \ + " + + local _not_found= + for _prog in ${_essential}; do + if [[ -z "$(which ${_prog/*:})" ]]; then + _not_found+=" ${_prog}" + fi + done + + if [[ ! -z "$_not_found" ]]; then + clear + echo -e "Os seguintes pacotes/programas são necessários para o instalador:\n" + _pkgs= + for _prog in ${_not_found}; do + echo " - ${_prog/:*}: ${_prog/*:}" + _pkgs+="${_prog/:*} " + done + read -p \ + $"Aperte ENTER para instalar os pacotes agora [CTRL+C para cancelar]: " + apt-get update + apt-get install -yq ${_pkgs} + fi +} +self.check_essential + +# -- Import functions from local or remote scripts +function import { + case ${1} in + http?://*|ftp?://*) + _tmpfile=$(mktemp /tmp/${self}.import.XXXXX) + curl -ks ${1} -o ${_tmpfile} \ + && source ${_tmpfile} \ + && rm -f ${_tmpfile} + ;; + *) + source ${1} + ;; + esac + return ${?} +} + +# -- YAML Parser +function parsers.yaml { + local _index=$(echo "['${2}']" | sed "s/\./\'\]\[\'/g") + + python3 -c "import yaml; \ + f=yaml.safe_load(open('${1}'))${_index}; \ + print('\n'.join(str(i) for i in f) if type(f)==list else f); \ + " +} + +# == UI =======================================================================+================= # +# -- Import UI from dbtool +ui=${ui:-cli} +dbtool=https://raw.githubusercontent.com/infra7ti/dbtool/refs/heads/main +import ${dbtool}/lib/ui/${ui}.bash + +function cli.status { + ${ui}.${@:1:1} && ${ui}.print "${@:2}" + echo; return 0 +} + +function cli.title { + ${ui}.color blue + ${ui}.emphasis "$(${ui}.subitem "${@^^}")" + ${ui}.color none + ${ui}.line +} + +function cli.subtitle { + ${ui}.subitem "${@^^} \n" + printf "%0.s$(echo -ne "\u2508${NO_FMT}")" {1..80} + echo +} + +function cli.prompt { + read -p "$(${ui}.status tab "${1}")" ${2:-} k + echo ${k} +} + +# == Configuração do Sistema====================================================================== # + +function system.check_os { + import /etc/os-release + local _os_name=${NAME} + local _suite=${VERSION_CODENAME} + case ${_suite} in + noble|jammy) (${ui}.status info $"SO homologado: %s(%s)" ${_os_name} ${_suite}) ;; + bookworm) (${ui}.status info $"SO homologado: %s(%s)" ${_os_name} ${_suite}) ;; + trixie|*) (${ui}.status error $"SO não homologado: %s(%s)" ${_os_name} ${_suite} && exit 1) ;; + esac + return 0 +} + +function system.check_sudo { + # Check if user has sudo access + if ! [[ (0$(id -u) -eq 0 || "$(groups)" =~ "sudo") ]]; then + ${ui}.status error $"Por favor use um usuário com privilégios de sudo" + sleep 10 && exit 1 + fi +} + +function system.setlocale { + ${ui}.status info $"Configurando locales do sistema ..." + for _locale in C en_US pt_BR; do + sed -i "s/#\s\(${_locale}.UTF-8\)/\1/" /etc/locale.gen + done + ${ui}.color gold + locale-gen --keep-existing | while read line; do + ${ui}.status tab "${line}" + done + update-locale LANG=pt_BR.UTF-8 + ${ui}.color none; echo +} + +function system.check_net { + _exit= + + function _get_external_ip { + local _ip="$(curl -ks${1} --fail https://ifconfig.me/ || echo none)" + case ${_ip} in + none) echo "$(${ui}.color red)${_ip}$(${ui}.color gold)" ;; + *) echo "$(${ui}.color green)${_ip}$(${ui}.color gold)" ;; + esac + if [[ "${_ip}" == "none" ]]; then return ${1}; fi + } + + ${ui}.status info $"Estado da Conexão à Internet:" + ${ui}.color gold + ${ui}.status tab $"IPv4 público: %s" "$(_get_external_ip 4)" + ${ui}.status tab $"IPv6 público: %s" "$(_get_external_ip 6)" + ${ui}.color none; echo +} + +function system.setup_ntp { + ${ui}.status info $"Configurando fuso e hora do sistema ..." + ${ui}.color gold + if [[ ! -z "$(pidof systemd)" ]]; then + sudo timedatectl set-local-rtc 0 + sudo timedatectl set-timezone America/Sao_Paulo + sudo timedatectl set-ntp true + fi + sudo DEBIAN_FRONTEND=noninteractive \ + dpkg-reconfigure tzdata 2>&1 | while read line; do \ + ${ui}.status tab "$([ ! -z "${line}" ] && echo ${line})"; \ + done; + ${ui}.color none; +} + +function system.create_group { + local _group=${@:1:1} + local _opts=${@:2} + + # Create the Group + if ! [[ $(id -g ${_group} 2>/dev/null) ]]; then + groupadd ${_opts} ${_group} + fi +} + +function system.create_user { + local _user=${@:1:1} + local _groups=${@:2:1} + + if ! [[ $(id -u ${_user} 2>/dev/null) ]]; then + useradd -m -d /home/${_user} -U -s /bin/bash -G ${_groups} ${_user} + else + usermod -s /bin/bash -aG ${_groups} ${_user} + fi +} + +function system.setup_openssh { + echo "UseDNS no" > /etc/sshd_config.d/no_dns.conf + systemctl rertart ssh.service +} + +# == Instalação de Pacotes e Aplicativos ======================================================== # + +function system.install_pkgs { + import /etc/os-release + local _os_id=${ID} + case ${_os_id} in + ubuntu|debian) + ${ui}.status info $"Instalando os pacotes ..." \ + && sudo apt-get -qq update \ + && ${ui}.color gold \ + && ( \ + sudo apt-get -q -y install --no-install-suggests "${@}" 2>&1 \ + | while read line; do \ + ${ui}.status tab "${line}"; \ + done \ + ) \ + && ${ui}.color none \ + && ${ui}.status info $"Pacotes instalados com sucesso!" \ + || ${ui}.status info $"Erro ao instalar os pacotes!" + ;; + *) + ${ui}.status warn $"Não implementado." + check_os + ;; + esac + return 0 +} + +function system.remove_pkgs { + import /etc/os-release + local _os_id=${ID} + case ${_os_id} in + ubuntu|debian) + ${ui}.status info $"Removendo os pacotes ..." \ + && ${ui}.color gold \ + && ( \ + sudo apt-get -q -y purge --autoremove "${@}" 2>&1 \ + | while read line; do \ + ${ui}.status tab "${line}"; \ + done \ + ) \ + && ${ui}.color none \ + && ${ui}.status info $"Pacotes removidos com sucesso!" \ + || ${ui}.status info $"Erro ao remover os pacotes!" + ;; + *) + ${ui}.status warn $"Não implementado." + check_os + ;; + esac + return 0 +} + +function system.install_postgres { + local _pg_version=${1:-17} + local _citus_version=${2} + + local POSTRES_PACKAGES=" + libjemalloc2 \ + postgresql-${_pg_version} \ + " + + ${ui}.subtitle "PostgreSQL" + + ${ui}.status info $"Habilitando repositório: PostgreSQL-PGDG ..." + if [[ ! -f "/etc/apt/sources.list.d/pgdg.list" ]]; then + sudo install -d /usr/share/postgresql-common/pgdg \ + && sudo curl -kso /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \ + --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc \ + && sudo sh -c " \ + echo 'deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \ + https://apt.postgresql.org/pub/repos/apt ${VERSION_CODENAME}-pgdg main' \ + > /etc/apt/sources.list.d/pgdg.list" + fi + ${ui}.color gold + ${ui}.status tab "The repository is set up! You can now install packages." + ${ui}.color none + + local _pg_shared_preload= + if [[ ! -z "${_citus_version}" ]]; then + ${ui}.status info $"Habilitando repositório: PostgreSQL-Citus ..." + if [[ ! -f "/etc/apt/sources.list.d/citusdata_community.list" ]]; then + ${ui}.color gold + sudo curl -ks https://install.citusdata.com/community/deb.sh | bash 2>&1 \ + | while read line; do \ + ${ui}.status tab "${line}"; \ + done + ${ui}.color none + else + ${ui}.color gold + ${ui}.status tab "The repository is set up! You can now install packages." + ${ui}.color none + fi + POSTRES_PACKAGES+=" postgresql-${_pg_version}-citus-${_citus_version/*-}" + _pg_shared_preload+="citus" + fi + + system.install_pkgs ${POSTRES_PACKAGES} + + pg_conftool ${_pg_version} main set listen_addresses '*' + pg_conftool ${_pg_version} main set log_timezone 'America/Sao_Paulo' + pg_conftool ${_pg_version} main set shared_preload_libraries ${_pg_shared_preload} + + local _pg_hba_file="/etc/postgresql/${_pg_version}/main/pg_hba.conf" + sudo cat <<-EOF | sed 's/^\s*\(.*\)/\1/g' > ${_pg_hba_file} + # Local Administrative User + local all postgres peer + # "local" is for Unix domain socket connections only + local all all scram-sha-256 + # IPv4 local connections: + host all all 127.0.0.1/32 scram-sha-256 + host all all 0.0.0.0/0 scram-sha-256 + # IPv6 local connections: + host all all ::1/128 scram-sha-256 + host all all ::/0 scram-sha-256 + # Allow replication connections from localhost, by a user with the + # replication privilege. + #local replication all scram-sha-256 + #host replication all 127.0.0.1/32 scram-sha-256 + #host replication all ::1/128 scram-sha-256 +EOF + + ${ui}.status info $"Reiniciando o cluster [%s/%s] ... " ${_pg_version} "main" + pg_ctlcluster ${_pg_version} main restart + ${ui}.color gold + pg_lsclusters ${_pg_version} main | while read line; do \ + case "$line" in \ + *online*) ${ui}.color green ;; \ + *down*) ${ui}.color red ;; \ + esac; \ + ${ui}.status tab "${line}"; \ + done + ${ui}.color none + echo +} + +function system.install_pyenv { + local _pyenv_root=${@:1:1} + local _py_version=${@:2:1} + + PYENV_PACKAGES=" \ + gcc \ + libc6-dev \ + libreadline-dev \ + libssl-dev \ + libbz2-dev \ + zlib1g-dev \ + libsqlite3-dev \ + make \ + " + + ${ui}.subtitle "PyEnv (Python Environment)" + export PYENV_ROOT="${_pyenv_root:-/usr/local/share/pyenv}" + useradd -M -d ${PYENV_ROOT} -s /bin/bash -r -U pyenv >/dev/null 2>&1 || : + + [[ -d "${PYENV_ROOT}" ]] && \ + ${ui}.status info $"PyEnv já está configurado!\n" && \ + return 0 + system.install_pkgs ${PYENV_PACKAGES} + #rm -rf ${PYENV_ROOT} + ${ui}.status info $"Instalando PyENV [%s] ..." ${PYENV_ROOT} + ${ui}.color gold + curl -ks https://pyenv.run | bash 2>&1 \ + | while read line; do \ + case "${line}" in \ + Cloning*) ${ui}.status tab "${line}";; \ + esac; \ + done + ${ui}.color none + + ${ui}.status info $"Executando PyEnv Doctor [%s] ..." ${PYENV_ROOT} + ${ui}.color gold + __pyenv=${PYENV_ROOT}/bin/pyenv + ${__pyenv} doctor 2>&1 \ + | while read line; do \ + case "${line}" in \ + Congratulations*) ${ui}.color green && ${ui}.status tab "${line}";; \ + warning*|WARNING*) ${ui}.color orange && ${ui}.status tab "${line}";; \ + *error:*) ${ui}.color red && ${ui}.status tab "${line}";; \ + *) ${ui}.status tab "${line}";; \ + esac \ + done || exit ${?} + ${ui}.color none + + ${ui}.status info $"Instalando Python [%s] ..." ${_py_version} + ${ui}.color gold + ${__pyenv} install ${_py_version} \ + | while read line; do \ + case "${line}" in \ + warning*|WARNING*) ${ui}.color orange && ${ui}.status tab "${line}";; \ + error*|ERROR*) ${ui}.color red && ${ui}.status tab "${line}";; \ + *) ${ui}.status tab "${line}";; \ + esac \ + done || exit ${?} + ${ui}.color none + chgrp -R pyenv ${PYENV_ROOT} + chmod -R g+rw ${PYENV_ROOT} + system.remove_pkgs ${PYENV_PACKAGES} + echo + + cat <<-EOF | sed 's/^\s*\(.*\)/\1/g' > /etc/profile.d/pyenv.sh + export PYENV_ROOT="${PYENV_ROOT}" + [[ -d \$PYENV_ROOT/bin ]] && export PATH="\$PYENV_ROOT/bin:\$PATH" + eval "\$(pyenv init - bash)" + eval "\$(pyenv virtualenv-init -)" +EOF +} + + +# == Produtos SIG =======================================================================+======= # + +function download { + local _src="${1:-}" + local _dst="${2:-${CACHEDIR}/$(basename ${1})}" + local _quiet=${3:-} + + local _repo_home="dl.sigsolucoes.net.br:/pub/" + local _repo_user="dl" + + local _token=$(mktemp /tmp/${self}.dl.XXXXXX) + local _seek=$(($(grep -anE "^exit 0" ${0} | cut -d: -f1) - ${LINENO} + 1)) + local _message="$(tail -n +$(( ${LINENO} + ${_seek} )) ${0})" + + [[ -z "${_quiet}" ]] && ${ui}.status info $"Fazendo download [${_src}]" + (echo ${_message} | base64 -d \ + | bsdtar --passphrase ${token_pass} -C $(dirname ${_token}) -xOf - > ${_token} \ + && chmod 0400 ${_token} \ + && scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + -qi ${_token} "${_repo_user}@${_repo_home}/${_src}" "${_dst}" \ + && color=green || color=red; \ + ${ui}.color ${color}; \ + echo "${_src}" | sed "s/^\(.*\)/\ \ $(${ui}.item '')\1/g"; \ + ${ui}.color none; \ + ) + rm -f ${_token} +} + +function menu.produtos { + clear + ${ui}.init "%s [VERSÃO: %s] - CONFIGURAÇÃO DOS PRODUTOS\n" ${self^^} ${version} + #token_pass=$(${ui}.prompt "Senha de acesso aos downloads: " -s) + + token_pass="Sig%$ºluc03s" + ${ui}.status info $"Atualizando lista de produtos\n" + + _repo='installer' + download "${_repo}/config/produtos.yml" "${CACHEDIR}/produtos.yml" >/dev/null 2>&1 + download "${_repo}/config/versoes.yml" "${CACHEDIR}/versoes.yml" >/dev/null 2>&1 + + _produtos=$( \ + parsers.yaml ${CACHEDIR}/produtos.yml "produtos" \ + | sed "s/'/\"/g" \ + | jq "to_entries[] | select(.value.restricted|not) | .key" \ + | sed 's/"//g' | sort + ) + + ${ui}.title $"Instalar/Configurar Produtos:"; + _id=1 + declare -A produtos + for _pd in ${_produtos}; do + produtos["${_id}"]="${_pd}" + _pdpy=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${_pd}.python") + _name=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${_pd}.name") + _pdpv=$(parsers.yaml ${CACHEDIR}/versoes.yml "produtos.python${_pdpy/.*}.${_pd}") + ${ui}.status tab "$( \ + ${ui}.color blue)${_id}.$(${ui}.color none) $( \ + ${ui}.print "${_name} ["VERSÃO:" ${_pdpv#*/}]" \ + )" + let _id=_id+1 + done; echo + + ${ui}.status tab "$( \ + ${ui}.color blue)${_id}.$(${ui}.color none) $( \ + ${ui}.print $"Limpar downloads e terminar" \ + )" + ${ui}.line + ${ui}.prompt $"Selecione o produto: " id + + # Sair do instalador + [ 0${id} -eq 0${_id} ] && rm -rf ${CACHEDIR} && exit 0 + export PRODUTO=${produtos[$id]} +} + +function produto.download { + _repo='software' + + _pdpy=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.python") + _libs=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.download") + _pdpv=$(parsers.yaml ${CACHEDIR}/versoes.yml "produtos.python${_pdpy/.*}.${PRODUTO}") + + mkdir -p ${CACHEDIR}/${PRODUTO} + ${ui}.status info $"Fazendo download dos arquivos ..." + for _lib in ${_libs}; do + _lbpv=$(parsers.yaml ${CACHEDIR}/versoes.yml libs.python${_pdpy/.*}.${_lib}) + download "${_repo}/libs/${_lib}/${_lbpv/\/*}/${_lib}-${_lbpv#*/}.tar.gz" \ + "${CACHEDIR}/${PRODUTO}/${_lib}-${_lbpv#*/}.tar.gz" --quiet + done + download "${_repo}/${PRODUTO}/${_pdpv/\/*}/${PRODUTO}-${_pdpv#*/}.tar.gz" \ + "${CACHEDIR}/${PRODUTO}/${PRODUTO}-${_pdpv#*/}.tar.gz" --quiet + + chmod g+rx,o+rx ${CACHEDIR} + ${ui}.status info $"Download concluído." + #${ui}.prompt $"Pressione uma tecla para continuar ... " +} + +function produto.install { + mkdir -p /srv/sig + ln -snf /srv/sig /sig + + BUILD_PACKAGES=" \ + build-essential + libmysqlclient-dev + gcc + libbz2-dev + libcups2-dev + libevent-dev + libffi-dev + libfreetype6-dev + libfribidi-dev + libharfbuzz-dev + libjpeg8-dev + liblcms2-dev + libldap2-dev + liblzma-dev + libmysqlclient-dev + libncursesw5-dev + libopenjp2-7-dev + libpq-dev + libreadline-dev + libsasl2-dev + libsqlite3-dev + libssl-dev + libtiff5-dev + libwebp-dev + libxcb1-dev + libxml2-dev + libxmlsec1-dev + libxslt1-dev + llvm + make + ncurses-dev + pyqt5-dev + python3-pip + swig + tk-dev + zlib1g-dev + " + + # -- Instalando pacotes necessários + system.install_pkgs ${BUILD_PACKAGES} + + + _pdpy=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.python") + _name=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.name") + _libs=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.download") + _pdpv=$(parsers.yaml ${CACHEDIR}/versoes.yml "produtos.python${_pdpy/.*}.${PRODUTO}") + + useradd -m -d /srv/sig/${PRODUTO} -s /bin/bash -G pyenv -r -U ${PRODUTO} 2>/dev/null || : + cat /etc/skel/.bashrc > /srv/sig/${PRODUTO}/.bashrc + echo -e "\n# Load Python ${_pdpy}\npyenv local ${_pdpy} >/dev/null 2>&1" >> /srv/sig/${PRODUTO}/.bashrc + echo ${_pdpy} > /srv/sig/${PRODUTO}/.python-version + + ${ui}.status info $"Instalando produto [%s] ..." "${_name}" + ${ui}.color gold + runuser -l ${PRODUTO} -- python -m pip install --upgrade --user pip + runuser -l ${PRODUTO} -- python -m pip install --upgrade --user setuptools + for _lib in ${_libs}; do + [[ "${_lib}" == "stoqdrivers" ]] && continue + _lbpv=$(parsers.yaml ${CACHEDIR}/versoes.yml libs.python${_pdpy/.*}.${_lib}) + runuser -l ${PRODUTO} -- python -m pip install --user \ + "${CACHEDIR}/${PRODUTO}/${_lib}-${_lbpv#*/}.tar.gz" + done + + case "${PRODUTO}" in + sigerp) + _date=$(date +%Y%m%d%H%M%S) + _pdpy=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.python") + + # Addons SigERP + [[ -d "/srv/sig/${PRODUTO}/addons" ]] && \ + mv \ + /srv/sig/${PRODUTO}/addons \ + /srv/sig/${PRODUTO}/addons.${_date}.bak + mkdir -p /srv/sig/${PRODUTO}/{addons,config,logs,data-dir} /run/${PRODUTO} + tar -C /srv/sig/${PRODUTO}/addons/ \ + -xzf ${CACHEDIR}/${PRODUTO}/${PRODUTO}-${_pdpv#*/}.tar.gz + download "installer/config/${PRODUTO}/requirements.txt" \ + "/srv/sig/${PRODUTO}/addons/requirements.txt" + [[ -f "/srv/sig/${PRODUTO}/addons/requirements.txt" ]] && \ + runuser -l ${PRODUTO} -- \ + python -m pip install -r /srv/sig/${PRODUTO}/addons/requirements.txt --user + chown -R ${PRODUTO}: /srv/sig/${PRODUTO}/ /run/${PRODUTO} + + # Runner and systemd units + download "installer/config/${PRODUTO}/sigerp-runner-pyenv-${_pdpy}.sh" \ + "/srv/sig/${PRODUTO}/sigerp-runner" \ + && chmod +x "/srv/sig/${PRODUTO}/sigerp-runner" \ + && ln -snf \ + "/srv/sig/${PRODUTO}/sigerp-runner" \ + "/usr/local/bin/sigerp-runner" + download "installer/config/${PRODUTO}/sigerp.service" \ + "/srv/sig/${PRODUTO}/sigerp.service" \ + && ln -snf \ + "/srv/sig/${PRODUTO}/sigerp.service" \ + "/etc/systemd/system/sigerp.service" \ + && ln -snf \ + "sigerp.service" \ + "/etc/systemd/system/openerp.service" + download "installer/config/${PRODUTO}/sigerp@.service" \ + "/srv/sig/${PRODUTO}/sigerp@.service" \ + && ln -snf \ + "/srv/sig/${PRODUTO}/sigerp@.service" \ + "/etc/systemd/system/sigerp@.service" \ + && ln -snf \ + "sigerp.service@" \ + "/etc/systemd/system/openerp@.service" + + # Config file + download "installer/config/${PRODUTO}/sigerp-${_pdpy}.conf" \ + "/srv/sig/${PRODUTO}/config/sigerp.conf" + + # Artwork SigERP + download "installer/config/${PRODUTO}/artwork-sigerp.zip" \ + "${CACHEDIR}/${PRODUTO}/artwork-sigerp.zip" \ + && unzip -o -d \ + "/srv/sig/${PRODUTO}/.local/lib/python${_pdpy%.*}/site-packages/" \ + -x "${CACHEDIR}/${PRODUTO}/artwork-sigerp.zip" + + # Runtime dependencies + SIGERP_PACKAGES="libmysqlclient21" + system.install_pkgs ${SIGERP_PACKAGES} + + # Create/Alter PostgreSQL user + local _password=$(openssl rand -base64 32 | sed 's/\//|/g') + ${ui}.status info $"Criando/Atualizando usuário do banco de dados [%s]" ${PRODUTO} + sudo -iu postgres \ + psql -c \ + "CREATE USER ${PRODUTO} WITH \ + PASSWORD '${_password}' \ + CREATEDB;" \ + || \ + sudo -iu postgres \ + psql -c \ + "ALTER USER ${PRODUTO} WITH \ + PASSWORD '${_password}' \ + CREATEDB;" + + if [[ 0${?} -eq 0 ]]; then + sed -i "s/.*db_password.*/db_password = ${_password}/g" \ + "/srv/sig/${PRODUTO}/config/sigerp.conf" + ${ui}.status warn $"Senha de acesso ao banco de dados: %s" ${_password} + sleep 5 + fi + + systemctl daemon-reload + systemctl enable --now sigerp.service || : + ;; + sigpdv) + _date=$(date +%Y%m%d%H%M%S) + [[ -d "/srv/sig/${PRODUTO}/sigpdv" ]] && \ + mv \ + /srv/sig/${PRODUTO}/sigpdv \ + /srv/sig/${PRODUTO}/sigpdv.${_date}.bak + + # TODO: Simplificar essa baderna + SIGPV_PACKAGES=" + atop \ + mousepad \ + net-tools \ + qt5dxcb-plugin \ + system-config-printer \ + terminator \ + tmate \ + vim-nox \ + " + system.install_pkgs ${SIGPV_PACKAGES} + + mkdir -p /srv/sig/${PRODUTO}/sigpdv + mkdir -p /usr/local/sigext + mkdir -p /recebe + + download "installer/config/${PRODUTO}/${PRODUTO}-single-instance-fix.patch" \ + "${CACHEDIR}/sigpdv/${PRODUTO}-single-instance-fix.patch" + + tar -C /srv/sig/${PRODUTO}/ \ + -xzf ${CACHEDIR}/${PRODUTO}/${PRODUTO}-${_pdpv#*/}.tar.gz + patch -d /srv/sig/${PRODUTO}/sigpdv \ + -p0 < "${CACHEDIR}/sigpdv/${PRODUTO}-single-instance-fix.patch" + + ln -snf /srv/sig/${PRODUTO}/sigpdv /usr/local/ + + ln -snf \ + /srv/sig/${PRODUTO}/sigpdv \ + /srv/sig/sigpdv/.local/lib/python2.7/site-packages/ + + mkdir /srv/sig/sigpdv/.local/lib/python2.7/site-packages/share \ + && mv /srv/sig/${PRODUTO}/.local/share/kiwi \ + /srv/sig/sigpdv/.local/lib/python2.7/site-packages/share/ \ + && ln -snf \ + /srv/sig/sigpdv/.local/lib/python2.7/site-packages/share/kiwi \ + /srv/sig/${PRODUTO}/.local/share/ \ + + tar --transform="s|stoqdrivers/||" \ + -C /srv/sig/sigpdv/.local/lib/python2.7/site-packages/ \ + -xzf ${CACHEDIR}/${PRODUTO}/stoqdrivers-0.9.11.tar.gz \ + stoqdrivers/stoqdrivers + + download "installer/config/${PRODUTO}/requirements.txt" \ + "/srv/sig/${PRODUTO}/sigpdv/requirements.txt" + + download "installer/config/${PRODUTO}/${PRODUTO}-wrapper.sh" \ + "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" \ + && chmod +x "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-comanda \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-consulta-cda \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-pdvconfig \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-sigpdv \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-sigpve + + ln -snf /srv/sig/${PRODUTO}/${PRODUTO}/debian/icons/* \ + /usr/share/pixmaps/ + mkdir /usr/local/share/applications/ \ + && ln -snf \ + /srv/sig/${PRODUTO}/${PRODUTO}/debian/desktop-files/* \ + /usr/local/share/applications/ \ + && sed -i 's|/usr/bin|/usr/local/bin|g' /usr/local/share/applications/*.desktop \ + && update-desktop-database || : + + download "installer/config/${PRODUTO}/${PRODUTO}.sudo" \ + "/etc/sudoers.d/${PRODUTO}" \ + && chown root:root "/etc/sudoers.d/${PRODUTO}" \ + && chmod 600 "/etc/sudoers.d/${PRODUTO}" + + download "installer/config/${PRODUTO}/pdvconfig.cfg" \ + "/usr/local/sigext/pdvconfig.cfg" + + download "installer/config/${PRODUTO}/CliSiTef.ini" \ + "/usr/local/sigext/CliSiTef.ini" + + # PostgreSQL user and database + local _password=$(openssl rand -base64 32 | sed 's/\//|/g') + ${ui}.status info $"Criando/Atualizando usuário e banco de dados [%s]" ${PRODUTO} + sudo -iu postgres \ + psql -c \ + "CREATE USER ${PRODUTO} WITH \ + PASSWORD '${_password}' \ + CREATEDB;" \ + || \ + sudo -iu postgres \ + psql -c \ + "ALTER USER ${PRODUTO} WITH \ + PASSWORD '${_password}' \ + CREATEDB;" + + if [[ 0${?} -eq 0 ]]; then + sed -i "s/.*db_pdv_pass.*/db_pdv_pass = ${_password}/g" \ + "/usr/local/sigext/pdvconfig.cfg" + sudo -i -u postgres createdb -O ${PRODUTO} ${PRODUTO} >/dev/null 2>&1 || : + ${ui}.status warn $"Senha de acesso ao banco de dados: %s" ${_password} + sleep 5 + fi + + chown -R ${PRODUTO}: /usr/local/sigext /recebe + chmod -R g+rw /usr/local/sigext /recebe + # End TODO + + [[ -f "/srv/sig/${PRODUTO}/sigpdv/requirements.txt" ]] && \ + runuser -l ${PRODUTO} -- \ + python -m pip install -qq -r /srv/sig/${PRODUTO}/sigpdv/requirements.txt --user \ + && rm -f /srv/sig/${PRODUTO}/sigpdv/requirements.txt + chown -R ${PRODUTO}: /srv/sig/${PRODUTO}/ + + local _user=$(getent passwd | sed '/x:1000/!d;s/:.*//g') + usermod -aG ${PRODUTO} ${_user} + ;; + sigvpn) + ${ui}.status warn $"Não implementado." +# rm -f /etc/apt/trusted.gpg.d/openvpn*.gpg +# curl -fsSL https://swupdate.openvpn.net/repos/repo-public.gpg \ +# | gpg --dearmor \ +# > /etc/apt/trusted.gpg.d/openvpn-repo-public.gpg +# +# rm -f /etc/apt/sources.list.d/openvpn*.list +# echo "deb [arch=amd64] https://build.openvpn.net/debian/openvpn/stable ${suite} main" \ +# > /etc/apt/sources.list.d/openvpn-aptrepo.list +# +# system.install_pkgs openvpn tmate \ +# && cd /etc/openvpn/client \ +# && (mv ../${name}.* . > /dev/null 2>&1 || true) \ +# && download "installer/config/openvpn/ovpn-local.ovpn" ${name}.conf \ +# && chown daemon:daemon ${name}.conf ${name}.passwd \ +# && systemctl disable openvpn.service \ +# && systemctl enable openvpn-client@${name}.service \ +# && systemctl restart openvpn-client@${name}.service \ +# && echo "net.ipv4.tcp_window_scaling=1" > /etc/sysctl.d/50-openvpn.conf \ +# && cd - + ;; + esac + + #system.remove_pkgs ${BUILD_PACKAGES} + + ${ui}.color none + ${ui}.status info $"Instalação concluída. Reinicie o computador." + ${ui}.prompt $"Pressione ENTER para continuar ... " +} + + + + +function sig.setup_artwork { + return +} + +function sig.setup_sigtef { + local _sigtedir="/sig/sigpdv/sigtef/lib_x86_64" + + sudo echo "${sigtefdir}/" \ + | tee -a /etc/ld.so.conf.d/sigtef.so.conf \ + | xargs ldconfig -n "${sigtefdir}" +} + + + +# == Loop Principal =======================================================================+===== # + +clear +export LANG=${LANG:-'C.UTF-8'} +${ui}.init $"%s [VERSÃO: %s] - CONFIGURAÇÃO INICIAL\n" ${self^^} ${version} + +self.check_essential + +# -- Configuração do sistema +${ui}.title $"Reconfigurando o sistema operacional" +system.check_os +system.check_sudo +system.setlocale +system.check_net +system.setup_ntp + +${ui}.title $"Instalando e configurando serviços" +system.install_postgres 17 citus-13.0 +system.install_pyenv /usr/local/share/pyenv 2.7.18 + +${ui}.title $"Configurando contas de usuários" +system.create_user sig dialout,pyenv,sudo + +${ui}.status info $"CONFIGURAÇÃO INICIAL CONCLUÍDA!" +${ui}.init "" +${ui}.prompt $"Pressione ENTER para continuar ... " + +CACHEDIR=$(mktemp -d /tmp/${self}.cache.XXXXX) +while true; do + menu.produtos + produto.download + produto.install +done + +exit 0 +# Não mude a linha abaixo (a menos que queira chorar muito) +UEsDBBQACQAIAOpUr1rVRV13NgEAALwBAAAKABwAaWRfZWQyNTUxOVVUCQADiO4laN+aLGh1eAsAAQToAwAABOgDAAC6rOUSyGuP+/lz9/JAxBA8QKcXxm258ri2/3lrrYCDHyQKm7Ztm5V3EMXl+BJc/zkmKd66XsR+qmDzkvH2n155ufxDgAx1FCYux0GjDwyK9eYXsZwxR52aVGSY1HYU4Y6bZOto1pz2Y0xVBQbKuVK3QdpNP5b4wh17uKK7f7INVzXK/F4wIB7lqoZoYa6AElkdquAi75jarNXgFd5vspGtOU+HfNRTJJd/Q1PUgnHnxxqsIj4tekMImpwMoWQlQgFiLEp2bBZUUk+DehFzT6O8vaFGmCSSSjjTB4d+YKgPxNhCJN14+Xgis/nvGsS9qAJojOzjuhoMRKlX5cjtGYVR6avhXEgnOf/OhcCUfNToTAJC6ll/tov/meVGu34nI92G/MmNUUl5wRE98qZa3PFodLOhV351UEsHCNVFXXc2AQAAvAEAAFBLAQIeAxQACQAIAOpUr1rVRV13NgEAALwBAAAKABgAAAAAAAEAAADtgQAAAABpZF9lZDI1NTE5VVQFAAOI7iVodXgLAAEE6AMAAAToAwAAUEsFBgAAAAABAAEAUAAAAIoBAAAAAA== diff --git a/sig-installer-dev b/sig-installer-dev new file mode 100755 index 0000000..e0bf911 --- /dev/null +++ b/sig-installer-dev @@ -0,0 +1,849 @@ +#!/bin/bash +set -euo pipefail + +self=$(: "${0/*\/}"; echo ${_%%.*sh}) +version=2506.1 + +: ${LANG:=C.UTF-8} + +# Read the configuration from all config files found +CONFPATH="/etc/${self}:/usr/local/etc/${self}:.config:./config:." +for _p in ${CONFPATH//:/\ }; do + test -f ${_p}/${self}.conf && \ + . ${_p}/${self}.conf +done + +function cli() { + cli.__init__() { + local blob="\ + ZXhwb3J0IE5PX0ZNVD0iXDAzM1swbSIKZXhwb3J0IEZfQk9MRD0iXDAzM1sxbSIKCmV4cG9ydCBD \ + X05PTkU9IlwwMzNbMG0iCmV4cG9ydCBDX1JFRD0iXDAzM1szODs1OzltIgpleHBvcnQgQ19CTFVF \ + PSJcMDMzWzM4OzU7MTJtIgpleHBvcnQgQ19HUkVFTj0iXDAzM1szODs1OzJtIgpleHBvcnQgQ19P \ + UkFOR0U9IlwwMzNbMzg7NTsyMDhtIgpleHBvcnQgQ19HT0xEPSJcMDMzWzM4OzU7MjIwbSIKZXhw \ + b3J0IENfUFVSUExFPSJcMDMzWzM4OzU7NW0iCgpleHBvcnQgU19JTkZPPSIke0NfQkxVRX1cdTI2 \ + OTEgW2luZm9dICR7Tk9fRk1UfSAiCmV4cG9ydCBTX1NVQ0NFU1M9IiR7Q19HUkVFTn1cdTI2OTEg \ + W3N1Y2Nlc3NdICR7Tk9fRk1UfVx1MjcxMyAiCmV4cG9ydCBTX0RFQlVHPSIke0NfUFVSUExFfVx1 \ + MjY5MSBbZGVidWddJHtOT19GTVR9ICIKZXhwb3J0IFNfV0FSTj0iJHtDX09SQU5HRX1cdTI2OTEg \ + W3dhcm5pbmddICR7Tk9fRk1UfSAiCmV4cG9ydCBTX0VSUk9SPSIke0NfUkVEfVx1MjY5MSBbZXJy \ + b3JdICR7Tk9fRk1UfVx1MjcxNSAiCgpleHBvcnQgVV9JVEVNPSJcdTIxOTIiCgpleHBvcnQgQ09M \ + Uz0iJCgoICQodHB1dCBjb2xzKSAtIDEgKSkiCgpjbGkuc2VjdGlvbigpIHsKICBfX3NlY3Rpb24u \ + aGVhZGVyKCkgewogICAgX19zZWN0aW9uLnRpdGxlKCkgewogICAgICBwcmludGYgJCIke0A6MTox \ + fSIgXAogICAgICAgICQoZWNobyAtbmUgJHtGX0JPTER9JHtDX0JMVUV9JHtAOjI6MX0ke05PX0ZN \ + VH0pIFwKICAgICAgICAkKGVjaG8gLW5lICR7Q19PUkFOR0V9JHtAOjN9JHtOT19GTVR9KQogICAg \ + ICB9CiAgICBfX3NlY3Rpb24udGl0bGUudW5kZXJsaW5lKCkgewogICAgICBmb3IgaSBpbiAkKHNl \ + cSAxICR7Q09MU30pOyBkbyBcCiAgICAgICAgcHJpbnRmICIlcyIgJChlY2hvIC1uZSAiXHUyNTgx \ + Iik7IFwKICAgICAgZG9uZQogICAgfQogICAgX19zZWN0aW9uLnRpdGxlICIke0B9IgogICAgX19z \ + ZWN0aW9uLnRpdGxlLnVuZGVybGluZQogIH0KICBfX3NlY3Rpb24uY29udGVudCgpIHsKICAgIHBy \ + aW50ZiAiJTJzXG4iCiAgICBwcmludGYgIiVzIiAiJHtAfSIgfCBmb2xkIC1zdyAke0NPTFN9CiAg \ + fQogIF9fc2VjdGlvbi5mb290ZXIoKSB7CiAgICBfX3NlY3Rpb24uZm9vdGVyLmxpbmUoKSB7CiAg \ + ICAgIFsgLXogIiR7MTotfSIgXSAmJiBwcmludGYgIiVzXG4iCiAgICAgIGZvciBpIGluICQoc2Vx \ + IDEgJHtDT0xTfSk7IGRvIFwKICAgICAgICAgIHByaW50ZiAiJXMiICQoZWNobyAtbmUgIlx1MjUw \ + NCR7Tk9fRk1UfSIpOyBcCiAgICAgIGRvbmUgJiYgXAogICAgICBbIC16ICIkezE6LX0iIF0gJiYg \ + cHJpbnRmICIlMnNcbiIKICAgIH0KICAgIF9fc2VjdGlvbi5mb290ZXIubGluZQogIH0KICBfX3Nl \ + Y3Rpb24uaGVhZGVyICIke0A6MTozfSIKICBfX3NlY3Rpb24uY29udGVudCAiJHtAOjR9IgogIF9f \ + c2VjdGlvbi5mb290ZXIKfQpjbGkuc2VjdGlvbiAiJHtAfSIK \ + " + envfile=$(mktemp /tmp/sig-installer.env.XXXXXX) + echo $blob|base64 -di|grep -vE '^cli.*@' > ${envfile} + test -r ${envfile} && source ${envfile} + rm -f ${envfile} + } + cli.__init__ + clear +} + +# == Funções Gerais ============================================================================== # + +function self.check_sudo { + # Check if user has sudo access + if ! [[ (0$(id -u) -eq 0 || "$(groups)" =~ "sudo") ]]; then + echo -ne "${S_ERROR}" $"Este programa deve ser executado com 'sudo'.\n" + echo -ne "\\033[13G" $"Tente usar: ${C_BLUE}sudo ${0}${C_NONE}" + return 1 + fi +} + +function self.check_essential { + # We need at least some programs installed + local _essential=" \ + libarchive-tools:bsdtar \ + curl:curl \ + git-core:git \ + iproute2:ip \ + iputils-ping:ping \ + jq:jq \ + python3-yaml:jq \ + locales:locale-gen \ + openssh-server:sshd \ + sudo:sudo \ + tzdata:tzconfig \ + " + + not_found= + for _prog in ${_essential}; do + if [[ -z "$(which ${_prog/*:} 2>/dev/null)" ]]; then + not_found+=" ${_prog}" + fi + done + + if [[ ! -z "$not_found" ]]; then + echo -ne "${S_ERROR}Os seguintes pacotes/programas são necessários para o instalador:\n\n" + for _prog in ${not_found}; do + echo " - ${_prog/*:} [${_prog/:*}]" + done; + [[ 0${#not_found} -gt 0 ]] \ + && cmd="apt-get -qq update; apt-get -qq -y install " + printf "%2s\n" + for _prog in ${not_found}; do + echo " - Instalando ${_prog/:*}:" + cmd+="${_prog/:*} " + done; + echo $cmd + return 2 + fi +} + +eval cli +cli.section "%s [VERSÃO: %s]\n" \ + ${self^^} \ + ${version} \ + "$(self.check_sudo)" \ + "$(self.check_essential)" + +function self.decode() { + local _passphrase="Sig%$ºluc03s" + + tail -n +$(( \ + ${LINENO} + \ + $(\ + : "$( \ + grep -anP "^exit 0" ${0})"; \ + echo $(( ${_%%:*} - ${LINENO} + 2)) \ + ) \ + )) ${0} | base64 -d \ + | bsdtar \ + --passphrase ${_passphrase} \ + -xOf - + + return ${?} +} + +exit 1 +# -- Import functions from local or remote scripts +function import { + case ${1} in + http?://*|ftp?://*) + _tmpfile=$(mktemp /tmp/${self}.import.XXXXX) + curl -ks ${1} -o ${_tmpfile} \ + && source ${_tmpfile} \ + && rm -f ${_tmpfile} + ;; + *) + source ${1} + ;; + esac + return ${?} +} + +# -- YAML Parser +function parsers.yaml { + local _index=$(echo "['${2}']" | sed "s/\./\'\]\[\'/g") + + python3 -c "import yaml; \ + f=yaml.safe_load(open('${1}'))${_index}; \ + print('\n'.join(str(i) for i in f) if type(f)==list else f); \ + " +} + +# == UI =======================================================================+================= # +# -- Import UI from dbtool +ui=${ui:-cli} +dbtool=https://raw.githubusercontent.com/infra7ti/dbtool/refs/heads/main +import ${dbtool}/lib/ui/${ui}.bash + +_() { echo $"${1}"; } + +function cli.status { + ${ui}.${@:1:1} && ${ui}.print "${@:2}" + echo; return 0 +} + +function cli.title { + ${ui}.color blue + ${ui}.emphasis "$(${ui}.subitem "${@^^}")" + ${ui}.color none + ${ui}.line +} + +function cli.subtitle { + ${ui}.subitem "${@^^} \n" + printf "%0.s$(echo -ne "\u2508${NO_FMT}")" {1..80} + echo +} + +function cli.prompt { + read -p "$(${ui}.status tab "${1}")" ${2:-} k + echo ${k} +} + +# == Configuração do Sistema====================================================================== # + +function system.check_os { + import /etc/os-release + local _os_name=${NAME} + local _suite=${VERSION_CODENAME} + case ${_suite} in + noble|jammy) (${ui}.status info $"SO homologado: %s(%s)" ${_os_name} ${_suite}) ;; + bookworm) (${ui}.status info $"SO homologado: %s(%s)" ${_os_name} ${_suite}) ;; + trixie|*) (${ui}.status error $"SO não homologado: %s(%s)" ${_os_name} ${_suite} && exit 1) ;; + esac + return 0 +} + +function system.setlocale { + ${ui}.status info $"Configurando locales do sistema ..." + for _locale in C en_US pt_BR; do + sed -i "s/#\s\(${_locale}.UTF-8\)/\1/" /etc/locale.gen + done + ${ui}.color gold + locale-gen --keep-existing | while read line; do + ${ui}.status tab "${line}" + done + update-locale LANG=pt_BR.UTF-8 + ${ui}.color none; echo +} + +function system.check_net { + _exit= + + function _get_external_ip { + local _ip="$(curl -ks${1} --fail https://ifconfig.me/ || echo none)" + case ${_ip} in + none) echo "$(${ui}.color red)${_ip}$(${ui}.color gold)" ;; + *) echo "$(${ui}.color green)${_ip}$(${ui}.color gold)" ;; + esac + if [[ "${_ip}" == "none" ]]; then return ${1}; fi + } + + ${ui}.status info $"Estado da Conexão à Internet:" + ${ui}.color gold + ${ui}.status tab $"IPv4 público: %s" "$(_get_external_ip 4)" + ${ui}.status tab $"IPv6 público: %s" "$(_get_external_ip 6)" + ${ui}.color none; echo +} + +function system.setup_ntp { + ${ui}.status info $"Configurando fuso e hora do sistema ..." + ${ui}.color gold + if [[ ! -z "$(pidof systemd)" ]]; then + sudo timedatectl set-local-rtc 0 + sudo timedatectl set-timezone America/Sao_Paulo + sudo timedatectl set-ntp true + fi + sudo DEBIAN_FRONTEND=noninteractive \ + dpkg-reconfigure tzdata 2>&1 | while read line; do \ + ${ui}.status tab "$([ ! -z "${line}" ] && echo ${line})"; \ + done; + ${ui}.color none; +} + +function system.create_group { + local _group=${@:1:1} + local _opts=${@:2} + + # Create the Group + if ! [[ $(id -g ${_group} 2>/dev/null) ]]; then + groupadd ${_opts} ${_group} + fi +} + +function system.create_user { + local _user=${@:1:1} + local _groups=${@:2:1} + + if ! [[ $(id -u ${_user} 2>/dev/null) ]]; then + useradd -m -d /home/${_user} -U -s /bin/bash -G ${_groups} ${_user} + else + usermod -s /bin/bash -aG ${_groups} ${_user} + fi +} + +function system.setup_openssh { + echo "UseDNS no" > /etc/sshd_config.d/no_dns.conf + systemctl rertart ssh.service +} + +# == Instalação de Pacotes e Aplicativos ======================================================== # + +function system.install_pkgs { + import /etc/os-release + local _os_id=${ID} + case ${_os_id} in + ubuntu|debian) + ${ui}.status info $"Instalando os pacotes ..." \ + && sudo apt-get -qq update \ + && ${ui}.color gold \ + && ( \ + sudo apt-get -q -y install --no-install-suggests "${@}" 2>&1 \ + | while read line; do \ + ${ui}.status tab "${line}"; \ + done \ + ) \ + && ${ui}.color none \ + && ${ui}.status info $"Pacotes instalados com sucesso!" \ + || ${ui}.status info $"Erro ao instalar os pacotes!" + ;; + *) + ${ui}.status warn $"Não implementado." + check_os + ;; + esac + return 0 +} + +function system.remove_pkgs { + import /etc/os-release + local _os_id=${ID} + case ${_os_id} in + ubuntu|debian) + ${ui}.status info $"Removendo os pacotes ..." \ + && ${ui}.color gold \ + && ( \ + sudo apt-get -q -y purge --autoremove "${@}" 2>&1 \ + | while read line; do \ + ${ui}.status tab "${line}"; \ + done \ + ) \ + && ${ui}.color none \ + && ${ui}.status info $"Pacotes removidos com sucesso!" \ + || ${ui}.status info $"Erro ao remover os pacotes!" + ;; + *) + ${ui}.status warn $"Não implementado." + check_os + ;; + esac + return 0 +} + +function system.install_postgres { + local _pg_version=${1:-17} + local _citus_version=${2} + + local POSTRES_PACKAGES=" + libjemalloc2 \ + postgresql-${_pg_version} \ + " + + ${ui}.subtitle "PostgreSQL" + + ${ui}.status info $"Habilitando repositório: PostgreSQL-PGDG ..." + if [[ ! -f "/etc/apt/sources.list.d/pgdg.list" ]]; then + sudo install -d /usr/share/postgresql-common/pgdg \ + && sudo curl -kso /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \ + --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc \ + && sudo sh -c " \ + echo 'deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \ + https://apt.postgresql.org/pub/repos/apt ${VERSION_CODENAME}-pgdg main' \ + > /etc/apt/sources.list.d/pgdg.list" + fi + ${ui}.color gold + ${ui}.status tab "The repository is set up! You can now install packages." + ${ui}.color none + + local _pg_shared_preload= + if [[ ! -z "${_citus_version}" ]]; then + ${ui}.status info $"Habilitando repositório: PostgreSQL-Citus ..." + if [[ ! -f "/etc/apt/sources.list.d/citusdata_community.list" ]]; then + ${ui}.color gold + sudo curl -ks https://install.citusdata.com/community/deb.sh | bash 2>&1 \ + | while read line; do \ + ${ui}.status tab "${line}"; \ + done + ${ui}.color none + else + ${ui}.color gold + ${ui}.status tab "The repository is set up! You can now install packages." + ${ui}.color none + fi + POSTRES_PACKAGES+=" postgresql-${_pg_version}-citus-${_citus_version/*-}" + _pg_shared_preload+="citus" + fi + + system.install_pkgs ${POSTRES_PACKAGES} + + pg_conftool ${_pg_version} main set listen.address '*' + pg_conftool ${_pg_version} main set log.timezone 'America/Sao_Paulo' + pg_conftool ${_pg_version} main set shared_preload_libraries ${_pg_shared_preload} + + local _pg_hba_file="/etc/postgresql/${_pg_version}/main/pg_hba.conf" + sudo cat <<-EOF | sed 's/^\s*\(.*\)/\1/g' > ${_pg_hba_file} + # "local" is for Unix domain socket connections only + local all all peer + # IPv4 local connections: + host all all 127.0.0.1/32 scram-sha-256 + host all all 0.0.0.0/0 scram-sha-256 + # IPv6 local connections: + host all all ::1/128 scram-sha-256 + host all all ::/0 scram-sha-256 + # Allow replication connections from localhost, by a user with the + # replication privilege. + #local replication all peer + #host replication all 127.0.0.1/32 scram-sha-256 + #host replication all ::1/128 scram-sha-256 +EOF + + ${ui}.status info $"Reiniciando o cluster [%s/%s] ... " ${_pg_version} "main" + pg_ctlcluster ${_pg_version} main restart + ${ui}.color gold + pg_lsclusters ${_pg_version} main | while read line; do \ + case "$line" in \ + *online*) ${ui}.color green ;; \ + *down*) ${ui}.color red ;; \ + esac; \ + ${ui}.status tab "${line}"; \ + done + ${ui}.color none +} + +function system.install_pyenv { + local _pyenv_root=${@:1:1} + local _py_version=${@:2:1} + + PYENV_PACKAGES=" \ + gcc \ + libc6-dev \ + libreadline-dev \ + libssl-dev \ + libbz2-dev \ + zlib1g-dev \ + libsqlite3-dev \ + make \ + " + + ${ui}.subtitle "PyEnv (Python Environment)" + export PYENV_ROOT="${_pyenv_root:-/usr/local/share/pyenv}" + useradd -M -d ${PYENV_ROOT} -s /bin/bash -r -U pyenv >/dev/null 2>&1 || : + + [[ -d "${PYENV_ROOT}" ]] && return 0 + system.install_pkgs ${PYENV_PACKAGES} + #rm -rf ${PYENV_ROOT} + ${ui}.status info $"Instalando PyENV [%s] ..." ${PYENV_ROOT} + ${ui}.color gold + curl -ks https://pyenv.run | bash 2>&1 \ + | while read line; do \ + case "${line}" in \ + Cloning*) ${ui}.status tab "${line}";; \ + esac; \ + done + ${ui}.color none + + ${ui}.status info $"Executando PyEnv Doctor [%s] ..." ${PYENV_ROOT} + ${ui}.color gold + __pyenv=${PYENV_ROOT}/bin/pyenv + ${__pyenv} doctor 2>&1 \ + | while read line; do \ + case "${line}" in \ + Congratulations*) ${ui}.color green && ${ui}.status tab "${line}";; \ + warning*|WARNING*) ${ui}.color orange && ${ui}.status tab "${line}";; \ + *error:*) ${ui}.color red && ${ui}.status tab "${line}";; \ + *) ${ui}.status tab "${line}";; \ + esac \ + done || exit ${?} + ${ui}.color none + + ${ui}.status info $"Instalando Python [%s] ..." ${_py_version} + ${ui}.color gold + ${__pyenv} install ${_py_version} \ + | while read line; do \ + case "${line}" in \ + warning*|WARNING*) ${ui}.color orange && ${ui}.status tab "${line}";; \ + error*|ERROR*) ${ui}.color red && ${ui}.status tab "${line}";; \ + *) ${ui}.status tab "${line}";; \ + esac \ + done || exit ${?} + ${ui}.color none + chgrp -R pyenv ${PYENV_ROOT} + chmod -R g+rw ${PYENV_ROOT} + system.remove_pkgs ${PYENV_PACKAGES} + echo + + cat <<-EOF | sed 's/^\s*\(.*\)/\1/g' > /etc/profile.d/pyenv.sh + export PYENV_ROOT="${PYENV_ROOT}" + [[ -d \$PYENV_ROOT/bin ]] && export PATH="\$PYENV_ROOT/bin:\$PATH" + eval "\$(pyenv init - bash)" + eval "\$(pyenv virtualenv-init -)" +EOF +} + + +# == Produtos SIG =======================================================================+======= # + +function download { + local _src="${1:-}" + local _dst="${2:-${CACHEDIR}/$(basename ${1})}" + local _quiet=${3:-} + + local _repo_home="dl.sigsolucoes.net.br:/pub/" + local _repo_user="dl" + + local _token=$(mktemp /tmp/${self}.dl.XXXXXX) + local _seek=$(($(grep -anE "^exit 0" ${0} | cut -d: -f1) - ${LINENO} + 1)) + local _message="$(tail -n +$(( ${LINENO} + ${_seek} )) ${0})" + + [[ -z "${_quiet}" ]] && ${ui}.status info $"Fazendo download [${_src}]" + (echo ${_message} | base64 -d \ + | bsdtar --passphrase ${token_pass} -C $(dirname ${_token}) -xOf - > ${_token} \ + && chmod 0400 ${_token} \ + && scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + -qi ${_token} "${_repo_user}@${_repo_home}/${_src}" "${_dst}" \ + && color=green || color=red; \ + ${ui}.color ${color}; \ + echo "${_src}" | sed "s/^\(.*\)/\ \ $(${ui}.item '')\1/g"; \ + ${ui}.color none; \ + ) + rm -f ${_token} +} + +function menu.produtos { + clear + ${ui}.init "%s [VERSÃO: %s] - CONFIGURAÇÃO DOS PRODUTOS\n" ${self^^} ${version} + #token_pass=$(${ui}.prompt "Senha de acesso aos downloads: " -s) + + token_pass="Sig%$ºluc03s" + ${ui}.status info $"Atualizando lista de produtos\n" + + _repo='installer' + download "${_repo}/config/produtos.yml" "${CACHEDIR}/produtos.yml" >/dev/null 2>&1 + download "${_repo}/config/versoes.yml" "${CACHEDIR}/versoes.yml" >/dev/null 2>&1 + + _produtos=$( \ + parsers.yaml ${CACHEDIR}/produtos.yml "produtos" \ + | sed "s/'/\"/g" \ + | jq "to_entries[] | select(.value.restricted|not) | .key" \ + | sed 's/"//g' | sort + ) + + ${ui}.title $"Instalar/Configurar Produtos:"; + _id=1 + declare -A produtos + for _pd in ${_produtos}; do + produtos["${_id}"]="${_pd}" + _pdpy=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${_pd}.python") + _name=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${_pd}.name") + _pdpv=$(parsers.yaml ${CACHEDIR}/versoes.yml "produtos.python${_pdpy/.*}.${_pd}") + ${ui}.status tab "$( \ + ${ui}.color blue)${_id}.$(${ui}.color none) $( \ + ${ui}.print "${_name} ["VERSÃO:" ${_pdpv#*/}]" \ + )" + let _id=_id+1 + done; echo + + ${ui}.status tab "$( \ + ${ui}.color blue)${_id}.$(${ui}.color none) $( \ + ${ui}.print $"Limpar downloads e terminar" \ + )" + ${ui}.line + ${ui}.prompt $"Selecione o produto: " id + + # Sair do instalador + [ 0${id} -eq 0${_id} ] && rm -rf ${CACHEDIR} && exit 0 + export PRODUTO=${produtos[$id]} +} + +function produto.download { + _repo='software' + + _pdpy=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.python") + _libs=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.download") + _pdpv=$(parsers.yaml ${CACHEDIR}/versoes.yml "produtos.python${_pdpy/.*}.${PRODUTO}") + + mkdir -p ${CACHEDIR}/${PRODUTO} + ${ui}.status info $"Fazendo download dos arquivos ..." + for _lib in ${_libs}; do + _lbpv=$(parsers.yaml ${CACHEDIR}/versoes.yml libs.python${_pdpy/.*}.${_lib}) + download "${_repo}/libs/${_lib}/${_lbpv/\/*}/${_lib}-${_lbpv#*/}.tar.gz" \ + "${CACHEDIR}/${PRODUTO}/${_lib}-${_lbpv#*/}.tar.gz" --quiet + done + download "${_repo}/${PRODUTO}/${_pdpv/\/*}/${PRODUTO}-${_pdpv#*/}.tar.gz" \ + "${CACHEDIR}/${PRODUTO}/${PRODUTO}-${_pdpv#*/}.tar.gz" --quiet + + chmod g+rx,o+rx ${CACHEDIR} + ${ui}.status info $"Download concluído." + #${ui}.prompt $"Pressione uma tecla para continuar ... " +} + +function produto.install { + mkdir -p /srv/sig + + + BUILD_PACKAGES=" \ + build-essential + libmysqlclient-dev + gcc + libbz2-dev + libcups2-dev + libevent-dev + libffi-dev + libfreetype6-dev + libfribidi-dev + libharfbuzz-dev + libjpeg8-dev + liblcms2-dev + libldap2-dev + liblzma-dev + libmysqlclient-dev + libncursesw5-dev + libopenjp2-7-dev + libpq-dev + libreadline-dev + libsasl2-dev + libsqlite3-dev + libssl-dev + libtiff5-dev + libwebp-dev + libxcb1-dev + libxml2-dev + libxmlsec1-dev + libxslt1-dev + llvm + make + ncurses-dev + pyqt5-dev + python3-pip + swig + tk-dev + zlib1g-dev + " + + # -- Instalando pacotes necessários + system.install_pkgs ${BUILD_PACKAGES} + + + _pdpy=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.python") + _name=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.name") + _libs=$(parsers.yaml ${CACHEDIR}/produtos.yml "produtos.${PRODUTO}.download") + _pdpv=$(parsers.yaml ${CACHEDIR}/versoes.yml "produtos.python${_pdpy/.*}.${PRODUTO}") + + useradd -m -d /srv/sig/${PRODUTO} -s /bin/bash -G pyenv -r -U ${PRODUTO} 2>/dev/null || : + cat /etc/skel/.bashrc > /srv/sig/${PRODUTO}/.bashrc + echo -e "\n# Load Python ${_pdpy}\npyenv local ${_pdpy} >/dev/null 2>&1" >> /srv/sig/${PRODUTO}/.bashrc + echo ${_pdpy} > /srv/sig/${PRODUTO}/.python-version + + ${ui}.status info $"Instalando produto [%s] ..." "${_name}" + ${ui}.color gold + runuser -l ${PRODUTO} -- python -m pip install --upgrade --user pip + runuser -l ${PRODUTO} -- python -m pip install --upgrade --user setuptools + for _lib in ${_libs}; do + [[ "${_lib}" == "stoqdrivers" ]] && continue + _lbpv=$(parsers.yaml ${CACHEDIR}/versoes.yml libs.python${_pdpy/.*}.${_lib}) + runuser -l ${PRODUTO} -- python -m pip install --user \ + "${CACHEDIR}/${PRODUTO}/${_lib}-${_lbpv#*/}.tar.gz" + done + + case "${PRODUTO}" in + sigerp) + _date=$(date +%Y%m%d%H%M%S) + [[ -d "/srv/sig/${PRODUTO}/addons" ]] && \ + mv \ + /srv/sig/${PRODUTO}/addons \ + /srv/sig/${PRODUTO}/addons.${_date}.bak + mkdir -p /srv/sig/${PRODUTO}/{addons,config} + tar -C /srv/sig/${PRODUTO}/addons/ \ + -xzf ${CACHEDIR}/${PRODUTO}/${PRODUTO}-${_pdpv#*/}.tar.gz + + download "installer/config/${PRODUTO}/requirements.txt" \ + "/srv/sig/${PRODUTO}/addons/requirements.txt" + + [[ -f "/srv/sig/${PRODUTO}/addons/requirements.txt" ]] && \ + runuser -l ${PRODUTO} -- \ + python -m pip install -r /srv/sig/${PRODUTO}/addons/requirements.txt --user + chown -R ${PRODUTO}: /srv/sig/${PRODUTO}/ + ;; + sigpdv) + _date=$(date +%Y%m%d%H%M%S) + [[ -d "/srv/sig/${PRODUTO}/sigpdv" ]] && \ + mv \ + /srv/sig/${PRODUTO}/sigpdv \ + /srv/sig/${PRODUTO}/sigpdv.${_date}.bak + + # PostgreSQL user and database + ${ui}.status info $"Criando usuário e banco de dados [%s]" ${PRODUTO} + sudo -i -u postgres createuser -d ${PRODUTO} >/dev/null 2>&1 || : + sudo -i -u postgres createdb -O ${PRODUTO} ${PRODUTO} >/dev/null 2>&1 || : + sudo -iu postgres psql -c "\password ${PRODUTO}" + ${ui}.status warn $"Não esqueça de alterar a senha no pdvconfig!" + + # TODO: Simplificar essa baderna + SIGPV_PACKAGES=" + atop \ + mousepad \ + net-tools \ + qt5dxcb-plugin \ + system-config-printer \ + terminator \ + tmate \ + vim-nox \ + " + system.install_pkgs ${SIGPV_PACKAGES} + + mkdir -p /srv/sig/${PRODUTO}/sigpdv + mkdir -p /usr/local/sigext + mkdir -p /recebe + + download "installer/config/${PRODUTO}/${PRODUTO}-single-instance-fix.patch" \ + "${CACHEDIR}/sigpdv/${PRODUTO}-single-instance-fix.patch" + + tar -C /srv/sig/${PRODUTO}/ \ + -xzf ${CACHEDIR}/${PRODUTO}/${PRODUTO}-${_pdpv#*/}.tar.gz + patch -d /srv/sig/${PRODUTO}/sigpdv \ + -p1 < "${CACHEDIR}/sigpdv/${PRODUTO}-single-instance-fix.patch" + + ln -snf /srv/sig/${PRODUTO}/sigpdv /usr/local/ + + ln -snf \ + /srv/sig/${PRODUTO}/sigpdv \ + /srv/sig/sigpdv/.local/lib/python2.7/site-packages/ + + mkdir /srv/sig/sigpdv/.local/lib/python2.7/site-packages/share \ + && mv /srv/sig/${PRODUTO}/.local/share/kiwi \ + /srv/sig/sigpdv/.local/lib/python2.7/site-packages/share/ \ + && ln -snf \ + /srv/sig/sigpdv/.local/lib/python2.7/site-packages/share/kiwi \ + /srv/sig/${PRODUTO}/.local/share/ \ + + tar --transform="s|stoqdrivers/||" \ + -C /srv/sig/sigpdv/.local/lib/python2.7/site-packages/ \ + -xzf ${CACHEDIR}/${PRODUTO}/stoqdrivers-0.9.11.tar.gz \ + stoqdrivers/stoqdrivers + + download "installer/config/${PRODUTO}/requirements.txt" \ + "/srv/sig/${PRODUTO}/sigpdv/requirements.txt" + + download "installer/config/${PRODUTO}/${PRODUTO}-wrapper.sh" \ + "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" \ + && chmod +x "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-comanda \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-consulta-cda \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-pdvconfig \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-sigpdv \ + && ln -snf "/srv/sig/${PRODUTO}/${PRODUTO}-wrapper.sh" /usr/local/bin/start-sigpve + + ln -snf /srv/sig/${PRODUTO}/${PRODUTO}/debian/icons/* \ + /usr/share/pixmaps/ + mkdir /usr/local/share/applications/ \ + && ln -snf \ + /srv/sig/${PRODUTO}/${PRODUTO}/debian/desktop-files/* \ + /usr/local/share/applications/ \ + && sed -i 's|/usr/bin|/usr/local/bin|g' /usr/local/share/applications/*.desktop \ + && update-desktop-database || : + + download "installer/config/${PRODUTO}/${PRODUTO}.sudo" \ + "/etc/sudoers.d/${PRODUTO}" \ + && chown root:root "/etc/sudoers.d/${PRODUTO}" \ + && chmod 600 "/etc/sudoers.d/${PRODUTO}" + + download "installer/config/${PRODUTO}/pdvconfig.cfg" \ + "/usr/local/sigext/pdvconfig.cfg" + + download "installer/config/${PRODUTO}/CliSiTef.ini" \ + "/usr/local/sigext/CliSiTef.ini" + + chown -R ${PRODUTO}: /usr/local/sigext /recebe + chmod -R g+rw /usr/local/sigext /recebe + # End TODO + + [[ -f "/srv/sig/${PRODUTO}/sigpdv/requirements.txt" ]] && \ + runuser -l ${PRODUTO} -- \ + python -m pip install -qq -r /srv/sig/${PRODUTO}/sigpdv/requirements.txt --user \ + && rm -f /srv/sig/${PRODUTO}/sigpdv/requirements.txt + chown -R ${PRODUTO}: /srv/sig/${PRODUTO}/ + + # TODO : autodetect user + usermod -aG ${PRODUTO} caixa + ;; + sigvpn) + ${ui}.status warn $"Não implementado." +# rm -f /etc/apt/trusted.gpg.d/openvpn*.gpg +# curl -fsSL https://swupdate.openvpn.net/repos/repo-public.gpg \ +# | gpg --dearmor \ +# > /etc/apt/trusted.gpg.d/openvpn-repo-public.gpg +# +# rm -f /etc/apt/sources.list.d/openvpn*.list +# echo "deb [arch=amd64] https://build.openvpn.net/debian/openvpn/stable ${suite} main" \ +# > /etc/apt/sources.list.d/openvpn-aptrepo.list +# +# system.install_pkgs openvpn tmate \ +# && cd /etc/openvpn/client \ +# && (mv ../${name}.* . > /dev/null 2>&1 || true) \ +# && download "installer/config/openvpn/ovpn-local.ovpn" ${name}.conf \ +# && chown daemon:daemon ${name}.conf ${name}.passwd \ +# && systemctl disable openvpn.service \ +# && systemctl enable openvpn-client@${name}.service \ +# && systemctl restart openvpn-client@${name}.service \ +# && echo "net.ipv4.tcp_window_scaling=1" > /etc/sysctl.d/50-openvpn.conf \ +# && cd - + ;; + esac + + system.remove_pkgs ${BUILD_PACKAGES} + + ${ui}.color none + ${ui}.status info $"Instalação concluída. Reinicie o computador." + ${ui}.prompt $"Pressione ENTER para continuar ... " +} + + + + +function sig.setup_artwork { + return +} + +function sig.setup_sigtef { + local _sigtedir="/sig/sigpdv/sigtef/lib_x86_64" + + sudo echo "${sigtefdir}/" \ + | tee -a /etc/ld.so.conf.d/sigtef.so.conf \ + | xargs ldconfig -n "${sigtefdir}" +} + + + +# == Loop Principal =======================================================================+===== # + +clear +export LANG=${LANG:-'C.UTF-8'} +${ui}.init $"%s [VERSÃO: %s] - CONFIGURAÇÃO INICIAL\n" ${self^^} ${version} + +self.check_essential + +# -- Configuração do sistema +${ui}.title $"Reconfigurando o sistema operacional" +system.check_os +system.check_sudo +system.setlocale +system.check_net +system.setup_ntp + +${ui}.title $"Instalando e configurando serviços" +system.install_postgres 17 citus-13.0 +system.install_pyenv /usr/local/share/pyenv 2.7.18 + +${ui}.title $"Configurando contas de usuários" +system.create_user sig dialout,pyenv,sudo + +${ui}.status info $"CONFIGURAÇÃO INICIAL CONCLUÍDA!" +${ui}.init "" +${ui}.prompt $"Pressione ENTER para continuar ... " + +CACHEDIR=$(mktemp -d /tmp/${self}.cache.XXXXX) +while true; do + menu.produtos + produto.download + produto.install +done + +exit 0 +# Não mude a linha abaixo (a menos que queira chorar muito) +UEsDBBQACQAIAOpUr1rVRV13NgEAALwBAAAKABwAaWRfZWQyNTUxOVVUCQADiO4laN+aLGh1eAsAAQToAwAABOgDAAC6rOUSyGuP+/lz9/JAxBA8QKcXxm258ri2/3lrrYCDHyQKm7Ztm5V3EMXl+BJc/zkmKd66XsR+qmDzkvH2n155ufxDgAx1FCYux0GjDwyK9eYXsZwxR52aVGSY1HYU4Y6bZOto1pz2Y0xVBQbKuVK3QdpNP5b4wh17uKK7f7INVzXK/F4wIB7lqoZoYa6AElkdquAi75jarNXgFd5vspGtOU+HfNRTJJd/Q1PUgnHnxxqsIj4tekMImpwMoWQlQgFiLEp2bBZUUk+DehFzT6O8vaFGmCSSSjjTB4d+YKgPxNhCJN14+Xgis/nvGsS9qAJojOzjuhoMRKlX5cjtGYVR6avhXEgnOf/OhcCUfNToTAJC6ll/tov/meVGu34nI92G/MmNUUl5wRE98qZa3PFodLOhV351UEsHCNVFXXc2AQAAvAEAAFBLAQIeAxQACQAIAOpUr1rVRV13NgEAALwBAAAKABgAAAAAAAEAAADtgQAAAABpZF9lZDI1NTE5VVQFAAOI7iVodXgLAAEE6AMAAAToAwAAUEsFBgAAAAABAAEAUAAAAIoBAAAAAA== diff --git a/tests/00-create-container.sh b/tests/00-create-container.sh new file mode 100644 index 0000000..d235dda --- /dev/null +++ b/tests/00-create-container.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +[[ "$(basename ${PWD})" == "tests" ]] && exit 1 +docker compose up -d diff --git a/tests/01-install-requires.sh b/tests/01-install-requires.sh new file mode 100755 index 0000000..5775c11 --- /dev/null +++ b/tests/01-install-requires.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +docker compose exec tests sh -c " + apt-get update \ + && apt-get -y install --no-install-suggests \ + curl \ + git-core \ + iproute2 \ + iputils-ping \ + jq \ + libarchive-tools \ + locales \ + python3-yaml \ + ssh \ + sudo \ + tzdata \ +" diff --git a/tests/90-run-container-shell.sh b/tests/90-run-container-shell.sh new file mode 100644 index 0000000..b04350e --- /dev/null +++ b/tests/90-run-container-shell.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker compose exec tests bash diff --git a/tests/90-run-sig-installer.sh b/tests/90-run-sig-installer.sh new file mode 100644 index 0000000..a604616 --- /dev/null +++ b/tests/90-run-sig-installer.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker compose exec tests sig-installer diff --git a/tests/99-destroy-container.sh b/tests/99-destroy-container.sh new file mode 100644 index 0000000..5e50d10 --- /dev/null +++ b/tests/99-destroy-container.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker compose down diff --git a/tests/compose.yml b/tests/compose.yml new file mode 100644 index 0000000..24c5265 --- /dev/null +++ b/tests/compose.yml @@ -0,0 +1,11 @@ +name: sig_installer +services: + + tests: + command: sh -c "while :; do sleep 30; done" + image: ubuntu:22.04 + user: root + volumes: + - ${PWD}:/usr/local/sbin:ro + ports: + - 8069:8069