#!/bin/bash set -euo pipefail self=$(: "${0/*\/}"; echo ${_%%.*sh}) version=2506.90 : ${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 { # Compressed built-in CLI cli.__init__() { local blob="\ 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 \ 0MMmahd1/gelgdo3VRQAAA== \ " envfile=$(mktemp /tmp/sig-installer.env.XXXXXX) echo $blob | base64 -di | gunzip -dc > ${envfile} test -r ${envfile} && source ${envfile} rm -f ${envfile} } cli.__init__ cli.clear } # == Funções Gerais ============================================================================== # function import { case ${1} in http?://*|ftp?://*) [[ -z "$(which curl 2>/dev/null)" ]] && return 1 _tmpfile=$(mktemp /tmp/${self}.import.XXXXX) curl -ks ${1} -o ${_tmpfile} \ && source ${_tmpfile} \ && rm -f ${_tmpfile} ;; *) source ${1} ;; esac return ${?} } function self.check_sudo { # Check if user has sudo access if ! [[ (0$(id -u) -eq 0 || "$(groups)" =~ "sudo") ]]; then cli.status info $"Este programa deve ser executado com 'sudo'" cli.tab 9; cli.item $"Tente usar: $(cli.emphasis red 'sudo') ${0}" echo -ne "\E[0G\n" return 1 fi } function self.check_os { local _os_id="${ID}" local _os_name=$(cli.emphasis bold "%s" "${NAME// /-}") local _os_version=" $(cli.bold "${VERSION/\(*}")"${VERSION/*\(/(}"" cli.status info $"Sistema operacional detectado: " cli.tab 9 case "${_os_id}" in ubuntu) cli.color orange "%s" "${_os_name}"; cli.print "${_os_version}" ;; debian) cli.color purple "%s" "${_os_name}"; cli.print "${_os_version}" ;; fedora) cli.color blue "%s" "${_os_name}"; cli.print "${_os_version}" ;; *) (printf "%s %s\n" "${_os_name}" "${_os_version}") ;; esac return 0 } function self.check_essential { # We need at least some programs installed local _essential_ubuntu=" \ libarchive-tools:/usr/bin/bsdtar \ curl:/usr/bin/curl \ git-core:/usr/bin/git \ iproute2:/usr/bin/ip \ iputils-ping:/usr/bin/ping \ jq:/usr/bin/jq \ python3-yaml:/usr/lib/python3/dist-packages/yaml \ locales:/usr/sbin/locale-gen \ openssh-server:/usr/sbin/sshd \ sudo:/usr/bin/sudo \ tzdata:/usr/sbin/tzconfig \ " local _essential_fedora=" \ bsdtar:/usr/bin/bsdtar \ curl:/usr/bin/curl \ git-core:/usr/bin/git \ iproute:/usr/bin/ip \ iputils:/usr/bin/ping \ jq:/usr/bin/jq \ python3-pyyaml:/usr/lib64/python$( \ python3 -V 2>/dev/null | grep -iPo 'Python \K.[\d]*\.[\d]*' \ )/site-packages/yaml \ glibc-common:/usr/lib/locale/C.utf8 \ glibc-langpack-en:/usr/lib/locale/en_US.utf8 \ glibc-langpack-pt:/usr/lib/locale/pt_BR.utf8 \ openssh-server:/usr/bin/sshd \ sudo:/usr/bin/sudo \ tzdata:/usr/share/zoneinfo \ " not_found= _essential=$(eval "echo \${_essential_${DISTRO}}") for _prog in ${_essential}; do if ! [[ -e "${_prog/*:}" ]] && [[ -z "$(which ${_prog/*:} 2>/dev/null)" ]]; then not_found+=" ${_prog}" fi done if [[ ! -z "$not_found" ]] || [[ 0${#not_found} -gt 0 ]]; then cli.status info "%s\n" $"As seguintes dependências são necessárias:" local _pkgs= for _prog in ${not_found}; do local _arrow=$(cli.color green "${U_ITEM}") printf " %s %s [%s]\n" ${_arrow} ${_prog/*:} $(cli.color green "${_prog/:*}") _pkgs+="${_prog/:*} " done; system.install_pkgs "${_pkgs}" return ${#_pkgs} fi } function self.get_token() { local _passphrase="Sig%$ºluc03s" tail -n +$(( \ ${LINENO} + \ $(\ : "$( \ grep -anP "^exit 0" ${0})"; \ echo $(( ${_%%:*} - ${LINENO} + 2)) \ ) \ )) ${0} | base64 -d \ | bsdtar \ --passphrase ${_passphrase} \ -xOf - return ${?} } # -- YAML Parser : parsers.yaml file.yml key function parsers.yaml { local \ out= err= parse() { python3 -c "import yaml; \ f=yaml.safe_load(open('${1}'))['${2//\./\'][\'}']; \ print('\n'.join(str(i) for i in f) if type(f)==list else f); \ " } if res=$(parse $@ 2>&1); then out=${res} && echo ${out} else err=$(: "${res//*\}"; echo "${_//:\ /: \[}]") ${ui}.status error "%s ${U_SUBITEM} %s " "${1##*\/} ${err}" $"NotFound" fi } # == 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_old { 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.install_pkgs { __buffer_output() { while mapfile -t -n ${1:-10} buffer && ((${#buffer[@]})); do cli.set_cursor 1 ${CURSOR_Y} printf "${C_PURPLE}" for line in "${buffer[@]}"; do ! [[ -z "${line}" ]] && printf " %s\n" "${line}${EL}" done; done } __apt_success() { cli.set_cursor 1 ${CURSOR_Y} printf "${S_SUCCESS}%s\n" \ "${@:1:1}:${EL}" for p in ${@:2}; do cli.tab 2; cli.item "${p}${EL}" done } __apt_failure() { cli.set_cursor 1 ${CURSOR_Y} printf "${S_ERROR}%s\n" \ "${@:1:1}:${EL}" if [[ -f "${2:-}" ]]; then tail -${4:-50} ${@:2:1} 2>/dev/null | while read line; do cli.tab 2; printf "${C_RED}${3:-Log}: %s\n" "${line}${EL}" done else cli.set_cursor 1 ${CURSOR_Y} cli.jump fi printf "\\E[0G${C_NONE}" } local _log=$(mktemp /tmp/${self}.install.XXXXX) case "${DISTRO}" in debian|ubuntu) printf "%0.s\n" export DEBIAN_FRONTEND=noninteractive cli.status info "%s\n" $"Instalando os pacotes. Por favor aguarde ..." cli.get_cursor apt-get -q update | tee ${_log} | \ __buffer_output 5 && \ apt-get -qy install ${@} 2>&1 | tee ${_log} | \ __buffer_output 10 \ && __apt_success $"Pacotes instalados com sucesso" ${@} \ || __apt_failure $"A instalação de pacotes falhou" ${_log} APT 50 printf "${C_NONE}%0.s\n" ;; fedora) cli.jump cli.status info "%s\n" $"Instalando os pacotes. Por favor aguarde ..." cli.get_cursor dnf -y install --refresh ${@} 2>&1 | tee ${_log} | \ __buffer_output 10 \ && __apt_success $"Pacotes instalados com sucesso" ${@} \ || __apt_failure $"A instalação de pacotes falhou" ${_log} DNF 50 printf "${C_NONE}%0.s\n" ;; *) cli.jump cli.status crit "%s" $"${DISTRO^}: Sistema operacional não suportado!" cli.jump ;; esac cli.get_cursor } 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 } # == Installer =================================================================================== # function installer.configure { local \ _passphrase=$(${ui}.prompt $"Frase secreta para acesso aos downloads: ") PRIVKEY_PASSPHRASE="${_passphrase}" ! [[ "X" == "${PRIVKEY_PASSPHRASE}X" ]] && \ ${ui}.status info $"Frase secreta armazenada com sucesso." ${_passphrase} } function installer.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 _token_pass=${PRIVKEY_PASSPHRASE} #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} \ (self.get_token > ${_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}; \ ! [[ "${_quiet}" == "silent" ]] \ && echo "${_src}" | sed "s/^\(.*\)/\ \ $(${ui}.item '')\1/g"; \ ${ui}.color none; \ ) rm -f ${_token} } function installer.download_metadata { local \ _metadata_uri="installer/config/sig-installer" \ _metadata_name="${1:-products}" installer.download \ "${_metadata_uri}/${_metadata_name}.yml" \ "${metadata_cache}/${_metadata_name}.yml" \ silent } function installer.load_products { local \ _product_metadata="${metadata_cache}/products.yml" \ _version_metadata="${metadata_cache}/versions.yml" \ _id _prod _products _products=$( \ parsers.yaml "${_product_metadata}" "products" \ | sed "s/'/\"/g" \ | jq "to_entries[] | select(.value.restricted|not) | .key" \ | sed 's/"//g' | sort ) echo "${_products}" } function installer.product.menu { metadata_cache="${CACHEDIR}" local \ _product_metadata="${metadata_cache}/products.yml" \ _version_metadata="${metadata_cache}/versions.yml" \ _products _prod_variant _prod_name _prod_color \ _prod_version _id _prod cli.set_cursor 0 0 cli.section "%s [VERSÃO: %s] - CONFIGURAÇÃO DE PRODUTOS${EL}\n" \ ${self^^} \ ${version} \ "$( ${ui}.status info $"Atualizando metadados de produtos... " installer.download_metadata products installer.download_metadata versions installer.download_metadata repos _products="$(installer.load_products)" )" #PRIVKEY_PASSPHRASE=Sig%$ºluc03s while [[ -z "${PRIVKEY_PASSPHRASE}" ]]; do installer.configure done exit 1 ${ui}.status info $"Atualizando metadados de produtos... " installer.download_metadata products installer.download_metadata versions installer.download_metadata repos _products="$(installer.load_products)" #${ui}.title $"Produtos:"; ${ui}.title $"Instalar/Atualizar Produtos:" _id=1 declare -A products for _prod in ${_products}; do products[${_id}]="${_prod}" _prod_variant=$(parsers.yaml "${_product_metadata}" "products.${_prod}.variant") _prod_name=$(parsers.yaml "${_product_metadata}" "products.${_prod}.name") _prod_color=$(parsers.yaml "${_product_metadata}" "products.${_prod}.color") _prod_version=$(parsers.yaml "${_version_metadata}" "products.${_prod}-${_prod_variant}") ${ui}.status tab "$( \ ${ui}.color blue)${_id}.$(${ui}.color none) $( \ ${ui}.print \ "%s (%s) [%s: %s]" \ "${F_BOLD}Sig${NO_FMT}$(${ui}.color ${_prod_color})${_prod_name#Sig*}${NO_FMT}" \ ${_prod_variant^} \ $"VERSÃO" $(${ui}.color orange)${_prod_version#*/}$(${ui}.color none) \ )" let _id=_id+1 done; echo ${ui}.subtitle $"Configurações:" ${ui}.status tab "$( \ ${ui}.color blue)C.$(${ui}.color none) $( \ ${ui}.print $"Configuração do Instalador" \ )" ${ui}.status tab "$( \ ${ui}.color blue)Q.$(${ui}.color none) $( \ ${ui}.print $"Limpar downloads e Sair" \ )" ${ui}.line ${ui}.prompt $"Selecione a opção: " id case ${id} in Q|q) rm -rf ${CACHEDIR} && exit 0 ;; C|c) installer.configure ;; *) true ;; esac [[ ${products[${id}]+x} ]] || return 0 PRODUCT=${products[$id]} } # == Products ==================================================================================== # function product.get_requires { import /etc/os-release local _os_id=${ID} _get_product_requires() { local \ _prod_metadata="${CACHEDIR}/products.yml" \ _version_metadata="${CACHEDIR}/versions.yml" \ _prod_name _prod_variant _prod_color _prod_paths \ _prod_requires _prod_buildreq _prod_config _prod_version \ _rq _br _pkg _repo ! [[ "X" == "${PRODUCT:-${1}}X" ]] || return 1 _prod_requires=$(parsers.yaml ${_prod_metadata} "products.${PRODUCT}.requires") _prod_buildreq=$(parsers.yaml ${_prod_metadata} "products.${PRODUCT}.buildrequires") # Not used here: #_prod_name=$(parsers.yaml ${_prod_metadata} "products.${PRODUCT}.name") #_prod_variant=$(parsers.yaml ${_prod_metadata} "products.${PRODUCT}.variant") #_prod_color=$(parsers.yaml ${_prod_metadata} "products.${PRODUCT}.color") #_prod_paths=$(parsers.yaml ${_prod_metadata} "products.${PRODUCT}.paths") #_prod_config=$(parsers.yaml ${_prod_metadata} "products.${PRODUCT}.config") #_prod_version=$(parsers.yaml ${_version_metadata} "products.${PRODUCT}-${_prod_variant}") for _rq in ${_prod_requires}; do [[ "${_rq}" =~ "${_os_id}" ]] && : "${_rq#*/}"; REQUIRES+="${_%~*} " done for _br in ${_prod_buildreq}; do [[ "${_br}" =~ "${_os_id}" ]] && : "${_br#*/}"; BUILD_REQUIRES+="${_%~*} " done for _pkg in ${_prod_requires} ${_prod_buildreq}; do : "${_pkg%"${_pkg##*\/}"}"; _repo=${_%\/*} case ${_repo} in ""|default) continue ;; local) echo "${_pkg}" >> ${CACHEDIR}/${PRODUCT}.local.build ;; sig) DOWNLOADS+="${_pkg} " ;; *) ! [[ "${REPOS}" =~ "${_repo}" ]] && REPOS+="${_repo} " esac done } _get_product_repos_requires() { local \ repo_metadata="${CACHEDIR}/repos.yml" \ _repo _repo_summary _repo_type _repo_dists \ _repo_requires _repo_buildreq _repo_script \ _rq _br for _repo in ${REPOS}; do _repo_requires=$(parsers.yaml ${repo_metadata} "repos.${_repo}.requires") _repo_buildreq=$(parsers.yaml ${repo_metadata} "repos.${_repo}.buildrequires") # Not used here: #_repo_summary=$(parsers.yaml ${repo_metadata} "repos.${_repo}.summary") #_repo_type=$(parsers.yaml ${repo_metadata} "repos.${_repo}.type") #_repo_dists=$(parsers.yaml ${repo_metadata} "repos.${_repo}.dists") #_repo_script=$(parsers.yaml ${repo_metadata} "repos.${_repo}.run") done for _rq in ${_repo_requires:-}; do [[ "${_rq}" =~ "${_os_id}" ]] && : "${_rq#*/}"; REQUIRES+="${_%~*} " done for _br in ${_repo_buildreq:-}; do [[ "${_br}" =~ "${_os_id}" ]] && : "${_br#*/}"; BUILD_REQUIRES+="${_%~*} " done } _get_product_requires _get_product_repos_requires #DEBUG=1 #${ui}.status info "%s: %s\n" $"Requires" "${REQUIRES}" #${ui}.status info "%s: %s\n" $"BuildRequires" "${BUILD_REQUIRES}" #${ui}.status info "%s: %s\n" $"Repos" "${REPOS}" #[[ ${DEBUG:-0} -gt 0 ]] && sleep 10 #return 0 } function product.setup_repos { local \ _repo _repo_name _repo_summary \ _repo_script _product.repo.get_property() { local \ __repo_metadata="${CACHEDIR}/repos.yml" \ __repo="${1:-}" \ __repo_property="${2:-}" echo "$(parsers.yaml ${__repo_metadata} "repos.${__repo}.${__repo_property}")" } for _repo in ${REPOS}; do _repo_name=${_repo} _repo_summary="$(_product.repo.get_property ${_repo} summary)" _repo_type=$(_product.repo.get_property ${_repo} type) ${ui}.status info $"Configurando Repositório [%s]" ${_repo_name} ${ui}.status tab $"Sumário: ${_repo_summary}\n" case ${_repo_type} in local) true ;; run) _repo_script=$(_product.repo.get_property ${_repo} run) ;; deb) echo "Não implementado" ;; rpm-md) echo "Não Implementado" ;; *) true ;; esac eval $(echo "${_repo_script}") done } function product.get_property { local \ _prod_variant \ _prod_verpath _get_property() { metadata_cache="${CACHEDIR}" local \ _product_metadata="${metadata_cache}/products.yml" \ _version_metadata="${metadata_cache}/versions.yml" \ _key=${PRODUCT}${1:-} echo $(parsers.yaml "${_product_metadata}" \ "products.${_key}") } _prod_variant=$(_get_property .variant) # Treat if product has variants: # true: verpath field comes from yaml key - # false: verpath field comes from yaml key ! [[ "${PRODUCT}" == "${_prod_variant}" ]] \ && _prod_verpath=$(_get_property -${_prod_variant}) \ || _prod_verpath=$(_get_property) case "${1:-}" in name) echo "$(_get_property .name)" ;; version) echo "$(basename ${_prod_verpath})" ;; variant) echo "$(_get_property .variant)" ;; dowload_uri) continue ;; cache_file) continue ;; *) true ;; esac } function product.download { metadata_cache="${CACHEDIR}" local \ _product_metadata="${metadata_cache}/products.yml" \ _version_metadata="${metadata_cache}/versions.yml" \ _prod_variant _prod_verpath _prod_download_uri \ _prod_root="software" _prod_output_dir _prod_file _lib \ _lib_root="software/libs" _lib_name _lib_variant _lib_verpath \ _lib_path _lib_download_uri _lib_file _ext="tar.gz" [[ -z "${PRODUCT}" ]] && return 1 _prod_variant=$(parsers.yaml "${_product_metadata}" \ "products.${PRODUCT}.variant") # Treat if product has variants: # true: verpath field comes from yaml key - # false: verpath field comes from yaml key ! [[ "${PRODUCT}" == "${_prod_variant}" ]] \ && _prod_verpath=$(parsers.yaml "${_version_metadata}" \ "products.${PRODUCT}-${_prod_variant}") \ || _prod_verpath=$(parsers.yaml "${_version_metadata}" \ "products.${PRODUCT}") _get_download_uri() { local _p=$(dirname "${3}") ! [[ "${_p}" == "." ]] && _p="${_p}/" || _p= echo "${1}/${2}/${_p}${2}-${3/*\/}.${4:-tar.gz}" } _get_output_file() { echo "${metadata_cache}/${PRODUCT}/${1}-${2/*\/}.${3:-tar.gz}" } #[[ "${@}" =~ '(ext=tar\.[bgxz]{2}\d*)' ]] \ # && _ext="${BASH_REMATCH[1]}" _prod_download_uri="$(_get_download_uri ${_prod_root} \ ${PRODUCT} ${_prod_verpath} ${_ext})" _prod_output_file="$(_get_output_file ${PRODUCT} \ ${_prod_verpath} ${_ext})" mkdir -p $(dirname ${_prod_output_file}) ${ui}.status info $"Fazendo download dos arquivos ..." installer.download \ "${_prod_download_uri}" \ "${_prod_output_file}" \ --quiet for _lib in ${DOWNLOADS}; do _lib_name=$(: "${_lib%:*}"; echo "${_#*\/}") _lib_variant=$(: "${_lib#*/}"; echo "${_#*:}") # Treat if library has variants: # true: verpath field comes from yaml key - # false: verpath field comes from yaml key ! [[ "${_lib_name}" == "${_lib_variant}" ]] \ && _lib_verpath=$(parsers.yaml "${_version_metadata}" \ "downloads.${_lib_name}-${_lib_variant}") \ || _lib_verpath=$(parsers.yaml "${_version_metadata}" \ "downloads.${_lib_name}") _lib_download_uri="$(_get_download_uri ${_lib_root} \ ${_lib_name} ${_lib_verpath} ${_ext})" _lib_output_file="$(_get_output_file ${_lib_name} \ ${_lib_verpath} ${_ext})" installer.download \ "${_lib_download_uri}" \ "${_lib_output_file}" \ --quiet done exit 1 chmod g+rx,o+rx ${CACHEDIR} ${ui}.status info $"Download concluído." #${ui}.prompt $"Pressione uma tecla para continuar ... " } function product.install { ${ui}.clear ${ui}.init $"%s [VERSÃO: %s] - INSTALAÇÃO DO PRODUTO\n" ${self^^} ${version} ${ui}.title "$(product.get_property name)" mkdir -p /srv/sig ln -snf /srv/sig /sig # -- Instalando pacotes necessários system.install_pkgs ${BUILD_REQUIRES} _pdpy=$(parsers.yaml ${CACHEDIR}/products.yml "products.${PRODUCT}.python") _name=$(parsers.yaml ${CACHEDIR}/products.yml "products.${PRODUCT}.name") _libs=$(parsers.yaml ${CACHEDIR}/products.yml "products.${PRODUCT}.download") _pdpv=$(parsers.yaml ${CACHEDIR}/versions.yml "products.python${_pdpy/.*}.${PRODUCT}") useradd -m -d /srv/sig/${PRODUCT} -s /bin/bash -G pyenv -r -U ${PRODUCT} 2>/dev/null || : cat /etc/skel/.bashrc > /srv/sig/${PRODUCT}/.bashrc echo -e "\n# Load Python ${_pdpy}\npyenv local ${_pdpy} >/dev/null 2>&1" >> /srv/sig/${PRODUCT}/.bashrc echo ${_pdpy} > /srv/sig/${PRODUCT}/.python-version ${ui}.status info $"Instalando produto [%s] ..." "${_name}" ${ui}.color gold runuser -l ${PRODUCT} -- python -m pip install --upgrade --user pip runuser -l ${PRODUCT} -- python -m pip install --upgrade --user setuptools for _lib in ${_libs}; do _lbpv=$(parsers.yaml ${CACHEDIR}/versions.yml libs.python${_pdpy/.*}.${_lib}) runuser -l ${PRODUCT} -- python -m pip install --user \ "${CACHEDIR}/${PRODUCT}/${_lib}-${_lbpv#*/}.tar.gz" if [[ "${_lib}" == "kiwi" ]]; then _f=/srv/sig/${PRODUCT}/.local/lib/python2.7/site-packages/kiwi/__installed__.py find $(dirname ${_f})/ -name *.pyc -delete download "installer/config/${PRODUCT}/__installed__.py" "${_f}" \ && chown -R ${PRODUCT}:${PRODUCT} "${_f}" \ && chmod 644 ${_f} \ && touch ${_f} fi done case "${PRODUCT}" in sigerp) _date=$(date +%Y%m%d%H%M%S) _pdpy=$(parsers.yaml ${CACHEDIR}/products.yml "products.${PRODUCT}.python") # Addons SigERP [[ -d "/srv/sig/${PRODUCT}/addons" ]] && \ mv \ /srv/sig/${PRODUCT}/addons \ /srv/sig/${PRODUCT}/addons.${_date}.bak mkdir -p /srv/sig/${PRODUCT}/{addons,config,logs,data-dir} /run/${PRODUCT} tar -C /srv/sig/${PRODUCT}/addons/ \ -xzf ${CACHEDIR}/${PRODUCT}/${PRODUCT}-${_pdpv#*/}.tar.gz download "installer/config/${PRODUCT}/requirements.txt" \ "/srv/sig/${PRODUCT}/addons/requirements.txt" [[ -f "/srv/sig/${PRODUCT}/addons/requirements.txt" ]] && \ runuser -l ${PRODUCT} -- \ python -m pip install -r /srv/sig/${PRODUCT}/addons/requirements.txt --user chown -R ${PRODUCT}: /srv/sig/${PRODUCT}/ /run/${PRODUCT} # Runner and systemd units download "installer/config/${PRODUCT}/sigerp-runner-pyenv-${_pdpy}.sh" \ "/srv/sig/${PRODUCT}/sigerp-runner" \ && chmod +x "/srv/sig/${PRODUCT}/sigerp-runner" \ && ln -snf \ "/srv/sig/${PRODUCT}/sigerp-runner" \ "/usr/local/bin/sigerp-runner" download "installer/config/${PRODUCT}/sigerp.service" \ "/srv/sig/${PRODUCT}/sigerp.service" \ && ln -snf \ "/srv/sig/${PRODUCT}/sigerp.service" \ "/etc/systemd/system/sigerp.service" \ && ln -snf \ "sigerp.service" \ "/etc/systemd/system/openerp.service" download "installer/config/${PRODUCT}/sigerp@.service" \ "/srv/sig/${PRODUCT}/sigerp@.service" \ && ln -snf \ "/srv/sig/${PRODUCT}/sigerp@.service" \ "/etc/systemd/system/sigerp@.service" \ && ln -snf \ "sigerp.service@" \ "/etc/systemd/system/openerp@.service" # Config file download "installer/config/${PRODUCT}/sigerp-${_pdpy}.conf" \ "/srv/sig/${PRODUCT}/config/sigerp.conf" # Artwork SigERP download "installer/config/${PRODUCT}/artwork-sigerp.zip" \ "${CACHEDIR}/${PRODUCT}/artwork-sigerp.zip" \ && unzip -o -d \ "/srv/sig/${PRODUCT}/.local/lib/python${_pdpy%.*}/site-packages/" \ -x "${CACHEDIR}/${PRODUCT}/artwork-sigerp.zip" # Runtime dependencies SIGERP_PACKAGES="\ atop \ libmysqlclient21 \ net-tools \ rclone \ tmate \ vim-nox \ " system.install_pkgs ${SIGERP_PACKAGES} # Create/Alter PostgreSQL user local _dbuser="openerp" local _password=$(openssl rand -base64 32 | sed 's/\//|/g') ${ui}.status info $"Criando/Atualizando usuário do banco de dados [%s]" ${PRODUCT} sudo -iu postgres \ psql -c \ "CREATE USER ${_dbuser} WITH \ PASSWORD '${_password}' \ CREATEDB;" \ || \ sudo -iu postgres \ psql -c \ "ALTER USER ${_dbuser} WITH \ PASSWORD '${_password}' \ CREATEDB;" if [[ 0${?} -eq 0 ]]; then sed -i "s/.*db_password.*/db_password = ${_password}/g" \ "/srv/sig/${PRODUCT}/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) # -- Faz o backup da pasta anterior do SigPDV [[ -d "/srv/sig/${PRODUCT}/sigpdv" ]] && \ mv \ /srv/sig/${PRODUCT}/sigpdv \ /srv/sig/${PRODUCT}/sigpdv.${_date}.bak # -- Cria a árvore de diretórios do SigPDV mkdir -p /srv/sig/${PRODUCT}/sigpdv mkdir -p /usr/local/sigext mkdir -p /recebe # -- Instala pacotes necessários para rodar o programa SIGPV_PACKAGES=" atop \ libmysqlclient21 \ mousepad \ net-tools \ qt5dxcb-plugin \ system-config-printer \ terminator \ rclone \ tmate \ vim-nox \ " system.install_pkgs ${SIGPV_PACKAGES} # -- Download e instalação dos addons e aplicação de correções tar -C /srv/sig/${PRODUCT}/ \ -xzf ${CACHEDIR}/${PRODUCT}/${PRODUCT}-${_pdpv#*/}.tar.gz ln -snf \ /srv/sig/${PRODUCT}/sigpdv \ /srv/sig/sigpdv/.local/lib/python2.7/site-packages/ ln -snf \ /srv/sig/${PRODUCT}/sigpdv \ /usr/local/ # Correção para erro "Dois frentes em execução" download "installer/config/${PRODUCT}/${PRODUCT}-single-instance-fix.patch" \ "${CACHEDIR}/sigpdv/${PRODUCT}-single-instance-fix.patch" patch -d /srv/sig/${PRODUCT}/sigpdv \ -p0 < "${CACHEDIR}/sigpdv/${PRODUCT}-single-instance-fix.patch" # -- Instalação dos módulos python de dependências download "installer/config/${PRODUCT}/requirements.txt" \ "/srv/sig/${PRODUCT}/sigpdv/requirements.txt" [[ -f "/srv/sig/${PRODUCT}/sigpdv/requirements.txt" ]] && \ runuser -l ${PRODUCT} -- \ python -m pip install -qq -r /srv/sig/${PRODUCT}/sigpdv/requirements.txt --user \ && rm -f /srv/sig/${PRODUCT}/sigpdv/requirements.txt # -- Lançadores dos programas download "installer/config/${PRODUCT}/${PRODUCT}-wrapper.sh" \ "/srv/sig/${PRODUCT}/${PRODUCT}-wrapper.sh" \ && chmod +x "/srv/sig/${PRODUCT}/${PRODUCT}-wrapper.sh" \ && ln -snf "/srv/sig/${PRODUCT}/${PRODUCT}-wrapper.sh" /usr/local/bin/start-comanda \ && ln -snf "/srv/sig/${PRODUCT}/${PRODUCT}-wrapper.sh" /usr/local/bin/start-consulta-cda \ && ln -snf "/srv/sig/${PRODUCT}/${PRODUCT}-wrapper.sh" /usr/local/bin/start-pdvconfig \ && ln -snf "/srv/sig/${PRODUCT}/${PRODUCT}-wrapper.sh" /usr/local/bin/start-sigpdv \ && ln -snf "/srv/sig/${PRODUCT}/${PRODUCT}-wrapper.sh" /usr/local/bin/start-sigpve ln -snf \ /srv/sig/${PRODUCT}/${PRODUCT}/debian/icons/* \ /usr/share/pixmaps/ mkdir /usr/local/share/applications/ \ && ln -snf \ /srv/sig/${PRODUCT}/${PRODUCT}/debian/desktop-files/* \ /usr/local/share/applications/ \ && sed -i 's|/usr/bin|/usr/local/bin|g' /usr/local/share/applications/*.desktop \ && update-desktop-database || : # -- Configuração padrão inicial download "installer/config/${PRODUCT}/pdvconfig.cfg" \ "/usr/local/sigext/pdvconfig.cfg" download "installer/config/${PRODUCT}/CliSiTef.ini" \ "/usr/local/sigext/CliSiTef.ini" for amb in homologacao producao lib_ssl_antiga; do ln -snf \ "/usr/local/sigext/CliSiTef.ini" \ /srv/sig/${PRODUCT}/${PRODUCT}/sigtef/lib_x86_64/${amb}/ done # -- Configurações de segurança e dos usuários local _app_user=${PRODUCT} local _app_group=${_app_user} # Acesso do usuário do desktop local _desktop_user=$(getent passwd | sed '/x:1000/!d;s/:.*//g') usermod -aG ${_app_group},pyenv ${_desktop_user} # Configuração do sudo download "installer/config/${PRODUCT}/${PRODUCT}.sudo" \ "/etc/sudoers.d/${PRODUCT}" \ && chown root:root "/etc/sudoers.d/${PRODUCT}" \ && chmod 600 "/etc/sudoers.d/${PRODUCT}" # Permissões de usuários e grupos for dir in /srv/sig/${PRODUCT} /usr/local/sigext /recebe; do chown -R ${_app_user}:${_app_group} ${dir} chmod -R g+rw,o-rwx ${dir} done # -- Configuração do banco de dados PostgreSQL local _db_name=${PRODUCT} local _db_user=${_db_name} local _db_pass=$(openssl rand -base64 32 | sed 's/\//|/g') ${ui}.status info $"Configurando o banco de dados [%s]" ${_db_name}} sudo -iu postgres \ psql -c \ "CREATE USER ${_db_user} WITH \ PASSWORD '${_db_pass}' \ CREATEDB;" \ || \ sudo -iu postgres \ psql -c \ "ALTER USER ${_db_user} WITH \ PASSWORD '${_db_pass}' \ CREATEDB;" if [[ 0${?} -eq 0 ]]; then sed -i "s/.*db_pdv_pass.*/db_pdv_pass = ${_db_pass}/g" \ "/usr/local/sigext/pdvconfig.cfg" sudo -i -u postgres createdb -O ${_db_user} ${_db_name} >/dev/null 2>&1 || : ${ui}.status warn $"Senha de acesso ao banco de dados: %s" ${_db_pass} sleep 5 fi ;; sigvpn) import /etc/os-release ${ui}.status info $"Configurando repositório OpenVPN ..." local _name=suporte-sig local _suite=${VERSION_CODENAME} 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 ${ui}.status info $"Instalando pacotes..." system.install_pkgs openvpn tmate ${ui}.status info $"Configurando serviço VPN ..." while ! [[ -z "${_vpn_user}" ]]; do local _vpn_user=$(${ui}.prompt $"Login de usuário da VPN: ") done while ! [[ -z "${_vpn_pass}" ]]; do local _vpn_pass=$(${ui}.prompt $"Senha do usuário da VPN: ") done echo -ne "${_vpn_user}\n${_vpn_pass}\n" > /etc/openvpn/client/${_name}.passwd \ && cd /etc/openvpn/client \ && (rm -rf ../${_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 product.sigpdv.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 =======================================================================+===== # # MAIN import /etc/os-release export DISTRO="${ID}" eval cli ui=${ui:-cli} ${ui}.section "%s [VERSÃO: %s] - CONFIGURAÇÃO DO INSTALADOR\n" \ ${self^^} \ ${version} \ "$( self.check_sudo || exit ${?}; \ self.check_os || exit ${?}; \ )" self.check_essential # -- Configuração do sistema #${ui}.title $"Reconfigurando o sistema operacional" #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) PRIVKEY_PASSPHRASE= # Menu while true; do PRODUCT= installer.product.menu REPOS= REQUIRES= BUILD_REQUIRES= DOWNLOADS= product.get_requires #product.setup_repos product.download product.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==