1206 lines
39 KiB
Bash
Executable File
1206 lines
39 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
self=$(: "${0/*\/}"; echo ${_%%.*sh})
|
|
version=2508.01
|
|
|
|
: ${LANG:=C.UTF-8}
|
|
|
|
rm -rf /tmp/${self}.*
|
|
CACHEDIR=$(mktemp -d /tmp/${self}.cache.XXXXX)
|
|
PRIVKEY_PASSPHRASE=
|
|
|
|
# Read the configuration from all config files found
|
|
CONFPATH="/etc/${self}:/usr/local/etc/${self}:./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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 \
|
|
"
|
|
envfile=$(mktemp /tmp/sig-installer.env.XXXXXX)
|
|
echo $blob | base64 -di | gunzip -dc > ${envfile}
|
|
test -r ${envfile} && source ${envfile}
|
|
rm -f ${envfile}
|
|
}
|
|
#source $(dirname $0)/builtin/cli.bash
|
|
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" "${_os_name}" "${_os_version}") ;;
|
|
esac
|
|
}
|
|
|
|
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//*\<module\>}"; echo "${_//:\ /: \[}]")
|
|
${ui}.status error "%s ${U_ITEM} %s" "${1##*\/} ${err}" $"NotFound"
|
|
fi
|
|
}
|
|
|
|
# == Configuração do Sistema====================================================================== #
|
|
|
|
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.setup_sshd {
|
|
echo "UseDNS no" > /etc/sshd_config.d/no_dns.conf
|
|
systemctl rertart ssh.service
|
|
}
|
|
|
|
# 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}
|
|
local _opts=${@:3}
|
|
|
|
if ! [[ $(id -u ${_user} 2>/dev/null) ]]; then
|
|
if [[ "${_opts}" =~ "-r" ]] || [[ "${_opts}" =~ "--system" ]]; then
|
|
${ui}.status info $"Creating system user: %s" ${_user}
|
|
useradd -M -U -G ${_groups} ${_opts} ${_user}
|
|
else
|
|
${ui}.status info $"Creating user: %s" ${_user}
|
|
useradd -m -d /home/${_user} -U -G ${_groups} ${_opts} ${_user}
|
|
fi
|
|
else
|
|
${ui}.status info $"Updating group membership for user: %s" ${_user}
|
|
usermod -aG ${_groups} ${_user}
|
|
fi
|
|
}
|
|
|
|
|
|
# == Instalação de Pacotes e Aplicativos ======================================================== #
|
|
|
|
function system.install_pkgs {
|
|
local _log=$(mktemp /tmp/${self}.apt-install.XXXXX)
|
|
case "${DISTRO}" in
|
|
debian|ubuntu)
|
|
${ui}.status info "%s" $"Aguarde. Instalando pacotes ..."
|
|
${ui}.get_cursor
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get \
|
|
-o Dpkg::Progress-Fancy=0 \
|
|
-o=Dpkg::Use-Pty=0 \
|
|
-q update \
|
|
| tee -a ${_log} \
|
|
| ${ui}.subprocess.output 10 && \
|
|
apt-get \
|
|
-o Dpkg::Progress-Fancy=0 \
|
|
-o=Dpkg::Use-Pty=0 \
|
|
-qqy install ${@} 2>&1 \
|
|
| tee -a ${_log} \
|
|
| ${ui}.subprocess.output 10 \
|
|
&& ${ui}.subprocess.success $"Pacotes instalados com sucesso" ${@} \
|
|
|| ${ui}.subprocess.failure $"A instalação de pacotes falhou" ${_log} APT 50
|
|
${ui}.writeln
|
|
;;
|
|
fedora)
|
|
${ui}.status info "%s\n" $"Aguarde. Instalando pacotes ..."
|
|
${ui}.get_cursor
|
|
dnf -y install --refresh ${@} 2>&1 | tee ${_log} | \
|
|
${ui}.subprocess.output 10 \
|
|
&& ${ui}.subprocess.success $"Pacotes instalados com sucesso" ${@} \
|
|
|| ${ui}.subprocess.failure $"A instalação de pacotes falhou" ${_log} DNF 50
|
|
${ui}.writeln
|
|
;;
|
|
*)
|
|
${ui}.status crit "%s" $"${DISTRO^}: Sistema operacional não suportado!"
|
|
${ui}.writeln
|
|
;;
|
|
esac
|
|
${ui}.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
|
|
}
|
|
|
|
# == Plugins: funções a serem separadas do instalador ============================================ #
|
|
|
|
function plugin.postgres {
|
|
local \
|
|
_pg_version=${1:-17} \
|
|
_pg_citus_version=${2:-} \
|
|
_pg_shared_preload= \
|
|
_pg_packages \
|
|
_pg_cluster \
|
|
_pg_hba_file \
|
|
_pg_port
|
|
|
|
_pg_packages="
|
|
libjemalloc2 \
|
|
postgresql-${_pg_version} \
|
|
"
|
|
_pg_check_repo() {
|
|
product.setup_repos ${1:-pgdg}
|
|
}
|
|
|
|
_pg_check_repo pgdg
|
|
if ! [[ -z "${_pg_citus_version}" ]]; then
|
|
_pg_check_repo citus
|
|
_pg_packages+=" postgresql-${_pg_version}-citus-${_pg_citus_version/*-}"
|
|
_pg_shared_preload+="citus"
|
|
fi
|
|
|
|
system.install_pkgs ${_pg_packages}
|
|
${ui}.lineup
|
|
${ui}.writeln
|
|
${ui}.writeln
|
|
|
|
_pg_cluster=$(pg_lsclusters | awk '/^17/ {print $2}')
|
|
${ui}.status info $"Configurando cluster PostgresSQL %s" "[${_pg_version}-${_pg_cluster}]"
|
|
|
|
pg_conftool ${_pg_version} ${_pg_cluster} set listen_addresses '*'
|
|
pg_conftool ${_pg_version} ${_pg_cluster} set log_timezone 'America/Sao_Paulo'
|
|
pg_conftool ${_pg_version} ${_pg_cluster} set shared_preload_libraries ${_pg_shared_preload}
|
|
|
|
_pg_port=$(pg_conftool \
|
|
${_pg_version} ${_pg_cluster} show port \
|
|
| grep -iPo '[0-9]*')
|
|
|
|
_pg_hba_file=$(pg_conftool \
|
|
${_pg_version} ${_pg_cluster} show hba_file \
|
|
| grep -iPo ".*[\'\"]\K[\S]*.conf")
|
|
|
|
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 $"Cluster configurado. Configuração (JSON): %s"
|
|
(
|
|
pg_conftool ${_pg_version} ${_pg_cluster} show all \
|
|
| jq -nR '{ "postgresql.conf": [ inputs ] }'; \
|
|
sed -e '/^#/d;s/\ \+/\ /g' "${_pg_hba_file}" \
|
|
| jq -nR '{ "pg_hba.conf": [ inputs ] }';
|
|
) | jq -s '.'; echo
|
|
${ui}.writeln
|
|
|
|
${ui}.status info $"Reiniciando o cluster " \
|
|
"$(${ui}.print "[%s/%s] ..." "${_pg_version}" "${_pg_cluster}")"
|
|
${ui}.writeln
|
|
|
|
echo
|
|
pg_ctlcluster ${_pg_version} ${_pg_cluster} restart
|
|
pg_lsclusters ${_pg_version} ${_pg_cluster} \
|
|
| awk '/(on|off)line/ { print $1"/"$2,"["$4"]:"}' \
|
|
| while read line; do
|
|
case "${line}" in
|
|
*"online"*)
|
|
${ui}.tab 2
|
|
${ui}.status success "$(${ui}.color green "${line}")"
|
|
${ui}.item "$(${ui}.color green "$(ss -nlt | grep ${_pg_port})")"
|
|
;;
|
|
*"down"*)
|
|
${ui}.tab 2
|
|
${ui}.status failure "$(${ui}.color red "${line}")"
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function plugin.pyenv {
|
|
local \
|
|
_pyenv_root=${@:1:1} \
|
|
_py_version=${@:2:1} \
|
|
__pyenv __python \
|
|
_log _py_test \
|
|
_profile_script
|
|
|
|
export PYENV_ROOT="${_pyenv_root:-/usr/local/share/pyenv}"
|
|
__pyenv=${PYENV_ROOT}/bin/pyenv
|
|
__python=${PYENV_ROOT}/versions/${_py_version}/bin/python
|
|
|
|
_pyenv.install() {
|
|
_log=$(mktemp /tmp/${self}.pyenv-install.XXXXX)
|
|
curl -ks https://pyenv.run | bash 2>&1 \
|
|
| grep Cloning \
|
|
| tee -a ${_log} \
|
|
| ${ui}.subprocess.output 5 \
|
|
&& (${ui}.subprocess.success $"PyEnv foi instalado com sucesso!" \
|
|
"${__pyenv}\u0020${U_ITEM}\u0020$(${__pyenv} -v | sed 's/pyenv\s*//')" \
|
|
) \
|
|
|| ${ui}.subprocess.failure $"Erro ao instalar PyEnv" ${_log} PYENV 50
|
|
${ui}.clear
|
|
${ui}.writeln
|
|
}
|
|
|
|
_pyenv.update() {
|
|
_log=$(mktemp /tmp/${self}.pyenv-update.XXXXX)
|
|
${__pyenv} update 2>&1 \
|
|
| tee -a ${_log} \
|
|
| grep -v '*' \
|
|
| ${ui}.subprocess.output 5 \
|
|
&& (${ui}.subprocess.success $"PyEnv foi atualizado com sucesso!" \
|
|
"${__pyenv}\u0020${U_ITEM}\u0020$(${__pyenv} -v | sed 's/pyenv\s*//')" \
|
|
) \
|
|
|| ${ui}.subprocess.failure $"Erro ao atualizar PyEnv" ${_log} PYENV 50
|
|
${ui}.clear
|
|
${ui}.writeln
|
|
}
|
|
|
|
_pyenv.doctor() {
|
|
_log=${1:-$(mktemp /tmp/${self}.pyenv-doctor.XXXXX)}
|
|
${__pyenv} doctor 2>&1 \
|
|
| tee -a ${_log} \
|
|
| ${ui}.subprocess.output 1 \
|
|
&& ${ui}.subprocess.success "$(tail -1 ${_log})" \
|
|
|| ${ui}.subprocess.failure "Falha" ${_log} PYENV 50
|
|
}
|
|
|
|
_pyenv.build() {
|
|
_log=${1:-$(mktemp /tmp/${self}.pyenv-python-build.XXXXX)}
|
|
env PYTHON_CONFIGURE_OPTS="--enable-shared" \
|
|
${__pyenv} install -fv ${_py_version} 2>&1 \
|
|
| tee -a ${_log} \
|
|
| ${ui}.subprocess.output 10 \
|
|
&& ${ui}.subprocess.success "$(${ui}.color green "$(tail -1 ${_log})")" \
|
|
|| ${ui}.subprocess.failure "Falha ao compilar Python" ${_log} PYENV 50
|
|
}
|
|
|
|
_pyenv.set_permissions() {
|
|
chgrp -R pyenv ${PYENV_ROOT}
|
|
chmod -R g+rw ${PYENV_ROOT}
|
|
}
|
|
|
|
_pyenv.set_environment() {
|
|
# Map pyenv python2 to system
|
|
ln -snf \
|
|
${_pyenv_root}/versions/${_py_version}/bin/{pip,python}2* \
|
|
/usr/local/bin/ || :
|
|
|
|
readarray -t _profile_script < <(echo \
|
|
"case \"\$(groups)\" in\n\
|
|
\t*\"pyenv\"*)\n\
|
|
\t\texport PYENV_ROOT=\"${PYENV_ROOT}\"\n\
|
|
\t\t[[ -d \"\${PYENV_ROOT}/bin\" ]] \
|
|
&& export PATH=\"\${PYENV_ROOT}/bin:\${PATH}\"\n\
|
|
\t\teval \"\$(pyenv init - bash)\"\n\
|
|
\t\t#eval \"\$(pyenv virtualenv-init -)\"\n\
|
|
\t;;\n\
|
|
\resac"
|
|
)
|
|
echo -e ${_profile_script[@]} \
|
|
| sed 's/\s*\r//g;s/\t/ /g' > /etc/profile.d/pyenv.sh
|
|
}
|
|
|
|
if [[ -x "${__pyenv}" ]]; then
|
|
${ui}.status info $"PyEnv já está instalado. Atualizando ..."
|
|
${ui}.get_cursor
|
|
_pyenv.update
|
|
else
|
|
${ui}.status info "$(${ui}.print $"Instalando PyEnv [%s] ..." ${PYENV_ROOT})"
|
|
${ui}.get_cursor
|
|
useradd -M -d ${PYENV_ROOT} -s /bin/bash -r -U pyenv >/dev/null 2>&1 || :
|
|
_pyenv.install
|
|
fi
|
|
${ui}.writeln
|
|
|
|
_py_test="$(${__python} -V 2>&1 || :)"
|
|
if [[ "${_py_test}" =~ "No such file or directory" ]]; then
|
|
_log=$(mktemp /tmp/${self}.pyenv-python-build.XXXXX)
|
|
rm -rf /tmp/python-*.log # Remove previous PyEnv logs
|
|
${ui}.status info "$(${ui}.print $"Verificando dependências ..." ${PYENV_ROOT})"
|
|
${ui}.get_cursor && _pyenv.doctor ${_log}
|
|
${ui}.status info "$(${ui}.print $"Compilando Python [%s] ..." ${_py_version})"
|
|
${ui}.get_cursor && _pyenv.build ${_log}
|
|
rm -rf /tmp/python-*.log # Remove current (duplicated) PyEnv logs
|
|
else
|
|
${ui}.status info $"Python já está instalado:"
|
|
${ui}.color green " $(${ui}.item "${__python}")"
|
|
${ui}.writeln
|
|
fi
|
|
${ui}.clear
|
|
${ui}.writeln
|
|
|
|
_pyenv.set_permissions
|
|
_pyenv.set_environment
|
|
${ui}.writeln
|
|
}
|
|
|
|
function plugin.pip {
|
|
local _metadata_cache="${CACHEDIR}"
|
|
local _version_metadata="${_metadata_cache}/versions.yml"
|
|
#local _py_version=${@:1:1}
|
|
|
|
# Retorna com erro se o produto não estiver definido
|
|
[[ -z "${PRODUCT}" ]] && return 1
|
|
local _product_cache="${CACHEDIR}/${PRODUCT}"
|
|
|
|
local __pip="runuser -l ${PRODUCT} -- python -m pip"
|
|
local _pip_log="$(mktemp ${_product_cache}/${self}.pip.XXXXX)"
|
|
|
|
_pip.download() {
|
|
for _pkg in ${DOWNLOADS}; do
|
|
local _pkg_name=$(: "${_pkg%:*}"; echo "${_#*\/}")
|
|
|
|
# Tratamento de variantes do pacote:
|
|
local _pkg_verpath _pkg_variant=$(: "${_pkg#*/}"; echo "${_#*:}")
|
|
if ! [[ "${_pkg_name}" == "${_pkg_variant}" ]]; then
|
|
# true: _pkg_verpath vem da chave yaml <product>-<variant>
|
|
_pkg_verpath=$(parsers.yaml "${_version_metadata}" \
|
|
"downloads.${_pkg_name}-${_pkg_variant}")
|
|
else
|
|
# false: _pkg_verpath vem da chave yaml <product>
|
|
_pkg_verpath=$(parsers.yaml "${_version_metadata}" \
|
|
"downloads.${_pkg_name}")
|
|
fi
|
|
|
|
local _ext="tar.gz"
|
|
local _pkg_root="software/libs"
|
|
local _pkg_download_uri="$(product.get_download_uri ${_pkg_root} \
|
|
${_pkg_name} ${_pkg_verpath} ${_ext})"
|
|
local _pkg_output_file="$(product.get_output_file ${_pkg_name} \
|
|
${_pkg_verpath} ${_ext})"
|
|
|
|
installer.download \
|
|
"${_pkg_download_uri}" \
|
|
"${_pkg_output_file}" \
|
|
--quiet && \
|
|
echo "file://${_pkg_output_file}" >> "${_product_cache}/requirements-local.txt"
|
|
done
|
|
}
|
|
|
|
_pip.install() {
|
|
local _pip_opts=" \
|
|
--disable-pip-version-check
|
|
"
|
|
# Instala pacotes e módulos do python
|
|
(
|
|
${__pip} ${_pip_opts} install --upgrade --user pip setuptools \
|
|
&& find "${_product_cache}"/ -maxdepth 1 -name "requirements*.txt" \
|
|
| xargs ${__pip} install -r
|
|
) 2>&1 \
|
|
| tee -a ${_pip_log} \
|
|
| ${ui}.subprocess.output 10 \
|
|
&& (
|
|
local _line; grep -iE 'installed|up-to-date' "${_pip_log}" \
|
|
| while read _line; do \
|
|
${ui}.tab 2
|
|
${ui}.item "$(${ui}.color green "${_line}${EL}")"
|
|
done
|
|
) \
|
|
|| ${ui}.subprocess.failure "Falha ao executar o PIP" ${_pip_log} PIP 100
|
|
${ui}.clear
|
|
${ui}.writeln
|
|
}
|
|
|
|
${ui}.status info $"Fazendo download dos pacotes python ..."
|
|
_pip.download
|
|
${ui}.writeln
|
|
|
|
${ui}.status info $"Instalando módulos python ..."
|
|
${ui}.get_cursor
|
|
_pip.install
|
|
${ui}.writeln
|
|
}
|
|
|
|
# == Installer =================================================================================== #
|
|
|
|
function installer.configure {
|
|
local _passphrase
|
|
${ui}.prompt $"Frase secreta para acesso aos downloads: " _passphrase
|
|
|
|
PRIVKEY_PASSPHRASE="${_passphrase}"
|
|
! [[ "X" == "${PRIVKEY_PASSPHRASE}X" ]] && \
|
|
${ui}.status info $"Frase secreta armazenada com sucesso."
|
|
}
|
|
|
|
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} \
|
|
&& mkdir -p $(dirname "${_dst}") \
|
|
&& 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.get_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.get_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.section "%s [VERSÃO: %s] - CONFIGURAÇÃO DE PRODUTOS${EL}\n" \
|
|
${self^^} \
|
|
${version} \
|
|
"$(
|
|
${ui}.status info "%s" $"Atualizando metadados de produtos... "
|
|
installer.get_metadata products
|
|
installer.get_metadata versions
|
|
installer.get_metadata repos
|
|
)"
|
|
|
|
${ui}.lineup 2
|
|
${ui}.status info "%s" $"Carregando lista de produtos... "
|
|
_products="$(installer.get_products)"
|
|
${ui}.writeln
|
|
|
|
${ui}.title $"Instalar/Atualizar Produtos:"
|
|
${ui}.subtitle $"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}.tab
|
|
# ${ui}.print "$( \
|
|
# ${ui}.color blue)${_id}.$(${ui}.color none) $( \
|
|
# ${ui}.print \
|
|
# "%s (%s) [%s: %s]" \
|
|
# "${F_BOLD}Sig${F_NONE}$(${ui}.color ${_prod_color})${_prod_name#Sig*}${F_NONE}" \
|
|
# ${_prod_variant^} \
|
|
# $"VERSÃO" $(${ui}.color orange)${_prod_version#*/}$(${ui}.color none) \
|
|
# )"
|
|
${ui}.print "[%s] %s%s (%s) [%s: %s]\n" \
|
|
"$(${ui}.color blue ${_id})" \
|
|
"Sig" \
|
|
"${_prod_name#Sig*}" \
|
|
"${_prod_variant}" \
|
|
"VERSÃO ${_prod_version#*/}"
|
|
let _id=_id+1
|
|
done; echo
|
|
|
|
${ui}.subtitle $"Configurações:"
|
|
|
|
${ui}.tab
|
|
printf "[%s] %s\n" \
|
|
"$(${ui}.color blue c)" \
|
|
$"Configuração do Instalador"
|
|
|
|
${ui}.tab
|
|
printf "[%s] %s\n" \
|
|
"$(${ui}.color blue q)" \
|
|
$"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.download {
|
|
local metadata_cache="${CACHEDIR}"
|
|
local _version_metadata="${metadata_cache}/versions.yml"
|
|
local _prod_files="${1:-}"
|
|
|
|
# Retorna com erro se o produto não estiver definido
|
|
[[ -z "${PRODUCT}" ]] && return 1
|
|
|
|
# Tratamento de variantes do produto:
|
|
local _prod_verpath _prod_variant=$(product.get_property variant)
|
|
if ! [[ "${PRODUCT}" == "${_prod_variant}" ]]; then
|
|
# true: _prod_verpath vem da chave yaml <product>-<variant>
|
|
_prod_verpath=$(parsers.yaml "${_version_metadata}" \
|
|
"products.${PRODUCT}-${_prod_variant}")
|
|
else
|
|
# false: _prod_verpath vem da chave yaml <product>
|
|
_prod_verpath=$(parsers.yaml "${_version_metadata}" \
|
|
"products.${PRODUCT}")
|
|
fi
|
|
|
|
# Define a extensão do arquivo principal do produto
|
|
local _ext="tar.gz"
|
|
#[[ "${@}" =~ '(ext=tar\.[bgxz]{2}\d*)' ]] \
|
|
# && _ext="${BASH_REMATCH[1]}"
|
|
|
|
local _prod_root="software"
|
|
local _prod_download_uri="$(product.get_download_uri ${_prod_root} \
|
|
${PRODUCT} ${_prod_verpath} ${_ext})"
|
|
local _prod_output_file="$(product.get_output_file ${PRODUCT} \
|
|
${_prod_verpath} ${_ext})"
|
|
|
|
# Download do arquivo principal do produto
|
|
mkdir -p $(dirname ${_prod_output_file})
|
|
${ui}.status info $"Fazendo download do produto ..."
|
|
installer.download \
|
|
"${_prod_download_uri}" \
|
|
"${_prod_output_file}" \
|
|
--quiet
|
|
#${ui}.writeln
|
|
|
|
# Download dos arquivos adicionais
|
|
local _files_root="installer"
|
|
local _keys=$(echo ${_prod_files//\'/\"} | jq 'keys_unsorted[]')
|
|
local _k; for _k in ${_keys[*]}; do
|
|
local _files=$(echo ${_prod_files//\'/\"} \
|
|
| jq ".${_k} |= join(\" \")" \
|
|
| jq ".${_k}"
|
|
)
|
|
local _file; for _file in ${_files}; do
|
|
installer.download \
|
|
"${_files_root}/config/${PRODUCT}/${_file//\"}" \
|
|
"${CACHEDIR}/${PRODUCT}/${_file//\"}" \
|
|
--quiet
|
|
done
|
|
done
|
|
|
|
exit 1
|
|
|
|
chmod g+rx,o+rx ${CACHEDIR}
|
|
#${ui}.status info $"Download concluído."
|
|
#${ui}.prompt $"Pressione uma tecla para continuar ... "
|
|
}
|
|
|
|
function product.get_download_uri {
|
|
local _p=$(dirname "${3}")
|
|
|
|
! [[ "${_p}" == "." ]] && _p="${_p}/" || _p=
|
|
echo "${1}/${2}/${_p}${2}-${3/*\/}.${4:-tar.gz}"
|
|
}
|
|
|
|
function product.get_output_file {
|
|
local metadata_cache="${CACHEDIR}"
|
|
echo "${metadata_cache}/${PRODUCT}/${1}-${2/*\/}.${3:-tar.gz}"
|
|
}
|
|
|
|
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 <product>-<variant>
|
|
# false: verpath field comes from yaml key <product>
|
|
! [[ "${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)" ;;
|
|
*) echo "$(_get_property ."${1:-}")" ;;
|
|
esac
|
|
|
|
}
|
|
|
|
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|pip) 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.install {
|
|
local metadata_cache="${CACHEDIR}"
|
|
|
|
cli.section "%s [VERSÃO: %s] - INSTALAÇÃO DO PRODUTOS${EL}\n" \
|
|
${self^^} \
|
|
${version} || :
|
|
|
|
${ui}.title $"Produto: " "$(product.get_property name)"
|
|
${ui}.subtitle $"Configuração Geral"
|
|
|
|
# -- Configura região e idioma do sistema
|
|
#system.setlocale pt_BR.UTF-8
|
|
|
|
# -- Cria/atualiza usuário e grupos do produto
|
|
local _user="$(product.get_property user.name)"
|
|
local _shell="$(product.get_property user.shell)"
|
|
local _home="$(product.get_property paths.home)"
|
|
local _groups="$(product.get_property user.groups)"
|
|
system.create_user "${_user}" ${_groups//\ /,} -s "${_shell}" -d "${_home}" -r
|
|
chown -R "${_user}:" "${_home}"
|
|
|
|
# -- Cria filesystem (diretórios) do produto
|
|
local _paths="$(product.get_property paths)"
|
|
local _keys="$(echo "${_paths//\'/\"}" | jq 'keys_unsorted[]')"
|
|
${ui}.status info $"Criando diretórios e links ... "
|
|
local _k; for _k in ${_keys[*]}; do
|
|
local _dir=$(echo "${_paths//\'/\"}" | jq ".${_k}" | sed 's/\"//g')
|
|
mkdir -p "${_dir}" \
|
|
&& (${ui}.tab; ${ui}.item "${_dir//\"/}") \
|
|
&& chown -R "${_user}:" "${_dir}"
|
|
done
|
|
${ui}.writeln
|
|
|
|
# -- Faz download do produto e arquivos relacionados
|
|
local _files="$(product.get_property files)"
|
|
product.download "${_files}"
|
|
unset _files
|
|
|
|
# -- Configurando repositórios
|
|
product.setup_repos ${REPOS}
|
|
|
|
# -- Instalando pacotes necessários
|
|
#DEV## system.install_pkgs ${BUILD_REQUIRES}
|
|
#DEV## ${ui}.prompt "Aguarde ou pressione ENTER para continuar ..." -s -t 10 || :
|
|
|
|
# -- Compilando requisitos não empacotados
|
|
_builds=$(grep "^local/" ${metadata_cache}/${PRODUCT}.local.build)
|
|
for _build in ${_builds}; do
|
|
_build=${_build#*/}
|
|
_type=${_build%:*}
|
|
_args=${_build#*:}
|
|
case "${_type}" in
|
|
plugin)
|
|
_callback="plugin.${_args%@*}"
|
|
_k_args=${_args#*@}
|
|
;;
|
|
esac
|
|
if ! [[ "no-clear" =~ "${_k_args}" ]]; then
|
|
${ui}.set_cursor 0 8
|
|
${ui}.get_cursor
|
|
${ui}.clear
|
|
fi
|
|
${ui}.subtitle $"Executando plugin: "${_args%@*}
|
|
${_callback} ${_k_args//;/\ }
|
|
${ui}.prompt "Aguarde ou pressione ENTER para continuar ..." -s -t 10 || :
|
|
done
|
|
|
|
## -- SIG ----------------------------- #
|
|
# # Pip modules
|
|
# ${ui}.status info $"Instalando produto [%s] ..." "${_name}"
|
|
# ${ui}.color gold
|
|
# 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
|
|
|
|
#system.remove_pkgs ${BUILD_REQUIRES}
|
|
|
|
${ui}.status info $"Instalação concluída. REINICIE o computador."
|
|
${ui}.prompt $"Pressione ENTER para continuar ... "
|
|
}
|
|
|
|
function product.setup_repos {
|
|
local \
|
|
_repos=${@:-} \
|
|
_repo
|
|
|
|
_product.repo.get_property() {
|
|
local \
|
|
__repo_metadata="${CACHEDIR}/repos.yml" \
|
|
__repo="${1:-}" \
|
|
__repo_property="${2:-}"
|
|
|
|
echo "$(parsers.yaml ${__repo_metadata} "repos.${__repo}.${__repo_property}")"
|
|
}
|
|
|
|
_product.repo.run_script() {
|
|
local \
|
|
__repo="${1:-}" \
|
|
__log=$(mktemp /tmp/sig-installer-${_repo}.XXXXX) \
|
|
__script=$(_product.repo.get_property ${1:-} run)
|
|
|
|
rm -rf /tmp/sig-installer-${__repo}.*.log
|
|
if ! [[ -z "${__script}" ]]; then
|
|
eval "$(echo "${__script}")" 2>&1 \
|
|
| tee -a ${__log} \
|
|
| ${ui}.subprocess.output 10 \
|
|
&& ${ui}.subprocess.success $"Repositório configurado com sucesso!" \
|
|
|| (
|
|
${ui}.subprocess.failure "Erro ao configurar repositório:" ${__log} REPOCFG 50;
|
|
${ui}.status debug "Script:\n%s" "${__script}";
|
|
)
|
|
${ui}.writeln
|
|
else
|
|
${ui}.status error "Erro ao configurar repositório:"
|
|
${ui}.status debug "Script:\n%s" "${__script}"
|
|
fi
|
|
}
|
|
|
|
for _repo in ${@:-}; do
|
|
local \
|
|
_repo_summary="$(_product.repo.get_property ${_repo} summary)" \
|
|
_repo_type=$(_product.repo.get_property ${_repo} type)
|
|
|
|
${ui}.status info "$(cli.print $"Configurando Repositório [%s]" ${_repo})"
|
|
${ui}.tab 2; ${ui}.item $"Descrição: ${_repo_summary}"
|
|
${ui}.get_cursor
|
|
|
|
case ${_repo_type} in
|
|
"copr") echo "Não implementado" ;;
|
|
"deb-list") echo "Não implementado" ;;
|
|
"deb-sources") echo "Não implementado" ;;
|
|
"flatpak") echo "Não implementado" ;;
|
|
"ppa") echo "Não implementado" ;;
|
|
"rpm-md") echo "Não implementado" ;;
|
|
"run") _product.repo.run_script "${_repo}" ;;
|
|
"snap") echo "Não implementado" ;;
|
|
"local") true ;;
|
|
"sig") true ;;
|
|
*) true ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
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}
|
|
|
|
clear
|
|
${ui}.section "%s [VERSÃO: %s] - CONFIGURAÇÃO DO INSTALADOR\n" \
|
|
${self^^} \
|
|
${version} \
|
|
"$(
|
|
self.check_sudo || exit ${?}; \
|
|
self.check_os || exit ${?}; \
|
|
)"
|
|
|
|
PRIVKEY_PASSPHRASE=Sig%$ºluc03s
|
|
while [[ -z "${PRIVKEY_PASSPHRASE}" ]]; do
|
|
installer.configure
|
|
done
|
|
|
|
self.check_essential
|
|
|
|
# -- Configuração do sistema
|
|
#${ui}.title $"Reconfigurando o sistema operacional"
|
|
#system.check_net
|
|
#system.setup_ntp
|
|
#system.setup_sshd
|
|
|
|
#${ui}.title $"Configurando contas de usuários"
|
|
#system.create_user sig dialout,pyenv,sudo
|
|
|
|
# Menu
|
|
while true; do
|
|
PRODUCT=
|
|
installer.product.menu
|
|
|
|
REPOS=
|
|
REQUIRES=
|
|
BUILD_REQUIRES=
|
|
DOWNLOADS=
|
|
product.get_requires
|
|
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==
|