Implementado downloads (parcial) e plugin PIP

This commit is contained in:
Christian Tosta
2025-08-01 13:15:56 -03:00
parent 37a8a05951
commit 56079c46be

View File

@@ -2,7 +2,7 @@
set -euo pipefail set -euo pipefail
self=$(: "${0/*\/}"; echo ${_%%.*sh}) self=$(: "${0/*\/}"; echo ${_%%.*sh})
version=2506.90 version=2508.01
: ${LANG:=C.UTF-8} : ${LANG:=C.UTF-8}
@@ -167,7 +167,7 @@ function self.check_essential {
fi fi
} }
function self.get_token() { function self.get_token {
local _passphrase="Sig%$ºluc03s" local _passphrase="Sig%$ºluc03s"
tail -n +$(( \ tail -n +$(( \
@@ -208,26 +208,6 @@ function parsers.yaml {
# == Configuração do Sistema====================================================================== # # == 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 { function system.setlocale {
${ui}.status info $"Configurando locales do sistema ..." ${ui}.status info $"Configurando locales do sistema ..."
for _locale in C en_US pt_BR; do for _locale in C en_US pt_BR; do
@@ -275,31 +255,40 @@ function system.setup_ntp {
${ui}.color none; ${ui}.color none;
} }
function system.create_group { function system.setup_sshd {
local _group=${@:1:1} echo "UseDNS no" > /etc/sshd_config.d/no_dns.conf
local _opts=${@:2} systemctl rertart ssh.service
# Create the Group
if ! [[ $(id -g ${_group} 2>/dev/null) ]]; then
groupadd ${_opts} ${_group}
fi
} }
# 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 { function system.create_user {
local _user=${@:1:1} local _user=${@:1:1}
local _groups=${@:2:1} local _groups=${@:2:1}
local _opts=${@:3}
if ! [[ $(id -u ${_user} 2>/dev/null) ]]; then if ! [[ $(id -u ${_user} 2>/dev/null) ]]; then
useradd -m -d /home/${_user} -U -s /bin/bash -G ${_groups} ${_user} if [[ "${_opts}" =~ "-r" ]] || [[ "${_opts}" =~ "--system" ]]; then
${ui}.status info $"Creating system user: %s" ${_user}
useradd -M -U -G ${_groups} ${_opts} ${_user}
else else
usermod -s /bin/bash -aG ${_groups} ${_user} ${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 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 ======================================================== # # == Instalação de Pacotes e Aplicativos ======================================================== #
@@ -584,6 +573,83 @@ function plugin.pyenv {
${ui}.writeln ${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 =================================================================================== # # == Installer =================================================================================== #
function installer.configure { function installer.configure {
@@ -600,7 +666,7 @@ function installer.download {
local _dst="${2:-${CACHEDIR}/$(basename ${1})}" local _dst="${2:-${CACHEDIR}/$(basename ${1})}"
local _quiet=${3:-} local _quiet=${3:-}
local _repo_home="dl.sigsolucoes.net.br:/pub/" local _repo_home="dl.sigsolucoes.net.br:/pub"
local _repo_user="dl" local _repo_user="dl"
local _token=$(mktemp /tmp/${self}.dl.XXXXXX) local _token=$(mktemp /tmp/${self}.dl.XXXXXX)
@@ -613,6 +679,7 @@ function installer.download {
# | bsdtar --passphrase ${_token_pass} -C $(dirname ${_token}) -xOf - > ${_token} \ # | bsdtar --passphrase ${_token_pass} -C $(dirname ${_token}) -xOf - > ${_token} \
(self.get_token > ${_token} \ (self.get_token > ${_token} \
&& chmod 0400 ${_token} \ && chmod 0400 ${_token} \
&& mkdir -p $(dirname "${_dst}") \
&& scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ && scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
-qi ${_token} "${_repo_user}@${_repo_home}/${_src}" "${_dst}" \ -qi ${_token} "${_repo_user}@${_repo_home}/${_src}" "${_dst}" \
&& color=green || color=red; \ && color=green || color=red; \
@@ -733,85 +800,80 @@ function installer.product.menu {
# == Products ==================================================================================== # # == Products ==================================================================================== #
function product.download { function product.download {
metadata_cache="${CACHEDIR}" local metadata_cache="${CACHEDIR}"
local _version_metadata="${metadata_cache}/versions.yml"
local \ local _prod_files="${1:-}"
_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"
# Retorna com erro se o produto não estiver definido
[[ -z "${PRODUCT}" ]] && return 1 [[ -z "${PRODUCT}" ]] && return 1
_prod_variant=$(parsers.yaml "${_product_metadata}" \ # Tratamento de variantes do produto:
"products.${PRODUCT}.variant") local _prod_verpath _prod_variant=$(product.get_property variant)
if ! [[ "${PRODUCT}" == "${_prod_variant}" ]]; then
# Treat if product has variants: # true: _prod_verpath vem da chave yaml <product>-<variant>
# true: verpath field comes from yaml key <product>-<variant> _prod_verpath=$(parsers.yaml "${_version_metadata}" \
# false: verpath field comes from yaml key <product> "products.${PRODUCT}-${_prod_variant}")
! [[ "${PRODUCT}" == "${_prod_variant}" ]] \ else
&& _prod_verpath=$(parsers.yaml "${_version_metadata}" \ # false: _prod_verpath vem da chave yaml <product>
"products.${PRODUCT}-${_prod_variant}") \ _prod_verpath=$(parsers.yaml "${_version_metadata}" \
|| _prod_verpath=$(parsers.yaml "${_version_metadata}" \
"products.${PRODUCT}") "products.${PRODUCT}")
fi
_get_download_uri() { # 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}") local _p=$(dirname "${3}")
! [[ "${_p}" == "." ]] && _p="${_p}/" || _p= ! [[ "${_p}" == "." ]] && _p="${_p}/" || _p=
echo "${1}/${2}/${_p}${2}-${3/*\/}.${4:-tar.gz}" echo "${1}/${2}/${_p}${2}-${3/*\/}.${4:-tar.gz}"
} }
_get_output_file() { function product.get_output_file {
local metadata_cache="${CACHEDIR}"
echo "${metadata_cache}/${PRODUCT}/${1}-${2/*\/}.${3:-tar.gz}" 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 <library>-<variant>
# false: verpath field comes from yaml key <library>
! [[ "${_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
chmod g+rx,o+rx ${CACHEDIR}
${ui}.status info $"Download concluído."
#${ui}.prompt $"Pressione uma tecla para continuar ... "
}
function product.get_property { function product.get_property {
local \ local \
_prod_variant \ _prod_variant \
@@ -842,7 +904,7 @@ function product.get_property {
name) echo "$(_get_property .name)" ;; name) echo "$(_get_property .name)" ;;
version) echo "$(basename ${_prod_verpath})" ;; version) echo "$(basename ${_prod_verpath})" ;;
variant) echo "$(_get_property .variant)" ;; variant) echo "$(_get_property .variant)" ;;
*) echo "$(_get_property ."${1:-}")" || : ;; *) echo "$(_get_property ."${1:-}")" ;;
esac esac
} }
@@ -885,7 +947,7 @@ function product.get_requires {
case ${_repo} in case ${_repo} in
""|default) continue ;; ""|default) continue ;;
local) echo "${_pkg}" >> ${CACHEDIR}/${PRODUCT}.local.build ;; local) echo "${_pkg}" >> ${CACHEDIR}/${PRODUCT}.local.build ;;
sig) DOWNLOADS+="${_pkg} " ;; sig|pip) DOWNLOADS+="${_pkg} " ;;
*) ! [[ "${REPOS}" =~ "${_repo}" ]] && REPOS+="${_repo} " *) ! [[ "${REPOS}" =~ "${_repo}" ]] && REPOS+="${_repo} "
esac esac
done done
@@ -930,7 +992,7 @@ function product.get_requires {
} }
function product.install { function product.install {
metadata_cache="${CACHEDIR}" local metadata_cache="${CACHEDIR}"
cli.section "%s [VERSÃO: %s] - INSTALAÇÃO DO PRODUTOS${EL}\n" \ cli.section "%s [VERSÃO: %s] - INSTALAÇÃO DO PRODUTOS${EL}\n" \
${self^^} \ ${self^^} \
@@ -939,29 +1001,40 @@ function product.install {
${ui}.title $"Produto: " "$(product.get_property name)" ${ui}.title $"Produto: " "$(product.get_property name)"
${ui}.subtitle $"Configuração Geral" ${ui}.subtitle $"Configuração Geral"
# -- Configura região e idioma do sistema
#system.setlocale pt_BR.UTF-8 #system.setlocale pt_BR.UTF-8
# TODO: move to PIP plugin # -- Cria/atualiza usuário e grupos do produto
#product.download local _user="$(product.get_property user.name)"
local _shell="$(product.get_property user.shell)"
_paths="$(product.get_property paths)" local _home="$(product.get_property paths.home)"
_keys="$(echo "${_paths//\'/\"}" | jq 'keys_unsorted[]')" 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 ... " ${ui}.status info $"Criando diretórios e links ... "
for _k in ${_keys[*]}; do local _k; for _k in ${_keys[*]}; do
_dir=$(echo "${_paths//\'/\"}" | jq ".${_k}") local _dir=$(echo "${_paths//\'/\"}" | jq ".${_k}" | sed 's/\"//g')
mkdir -p ${_dir} \ mkdir -p "${_dir}" \
&& (${ui}.tab; ${ui}.item "${_dir//\"/}") && (${ui}.tab; ${ui}.item "${_dir//\"/}") \
&& chown -R "${_user}:" "${_dir}"
done done
ln -snf /srv/sig /sig
${ui}.writeln ${ui}.writeln
# -- Faz download do produto e arquivos relacionados
local _files="$(product.get_property files)"
product.download "${_files}"
unset _files
# -- Configurando repositórios # -- Configurando repositórios
product.setup_repos ${REPOS} product.setup_repos ${REPOS}
# -- Instalando pacotes necessários # -- Instalando pacotes necessários
system.install_pkgs ${BUILD_REQUIRES} #DEV## system.install_pkgs ${BUILD_REQUIRES}
${ui}.prompt "Aguarde ou pressione ENTER para continuar ..." -s -t 10 || : #DEV## ${ui}.prompt "Aguarde ou pressione ENTER para continuar ..." -s -t 10 || :
# -- Compilando requisitos não empacotados # -- Compilando requisitos não empacotados
_builds=$(grep "^local/" ${metadata_cache}/${PRODUCT}.local.build) _builds=$(grep "^local/" ${metadata_cache}/${PRODUCT}.local.build)
@@ -975,26 +1048,20 @@ function product.install {
_k_args=${_args#*@} _k_args=${_args#*@}
;; ;;
esac esac
if ! [[ "no-clear" =~ "${_k_args}" ]]; then
${ui}.set_cursor 0 8 ${ui}.set_cursor 0 8
${ui}.get_cursor ${ui}.get_cursor
${ui}.clear ${ui}.clear
fi
${ui}.subtitle $"Executando plugin: "${_args%@*} ${ui}.subtitle $"Executando plugin: "${_args%@*}
${_callback} ${_k_args//;/\ } ${_callback} ${_k_args//;/\ }
${ui}.prompt "Aguarde ou pressione ENTER para continuar ..." -s -t 10 || : ${ui}.prompt "Aguarde ou pressione ENTER para continuar ..." -s -t 10 || :
done done
## -- SIG ----------------------------- # ## -- SIG ----------------------------- #
# TODO: Pyenv -> Use .python-version on user home!
# 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
#
# # Pip modules # # Pip modules
# ${ui}.status info $"Instalando produto [%s] ..." "${_name}" # ${ui}.status info $"Instalando produto [%s] ..." "${_name}"
# ${ui}.color gold # ${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 # for _lib in ${_libs}; do
# _lbpv=$(parsers.yaml ${CACHEDIR}/versions.yml libs.python${_pdpy/.*}.${_lib}) # _lbpv=$(parsers.yaml ${CACHEDIR}/versions.yml libs.python${_pdpy/.*}.${_lib})
# runuser -l ${PRODUCT} -- python -m pip install --user \ # runuser -l ${PRODUCT} -- python -m pip install --user \
@@ -1115,6 +1182,7 @@ self.check_essential
#${ui}.title $"Reconfigurando o sistema operacional" #${ui}.title $"Reconfigurando o sistema operacional"
#system.check_net #system.check_net
#system.setup_ntp #system.setup_ntp
#system.setup_sshd
#${ui}.title $"Configurando contas de usuários" #${ui}.title $"Configurando contas de usuários"
#system.create_user sig dialout,pyenv,sudo #system.create_user sig dialout,pyenv,sudo