Add initial setup scripts and configuration files for development environment
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
venv
|
||||
app/frontend/node_modules
|
||||
app/venv
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
# Usa Debian como base
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
# Definir el directorio de trabajo
|
||||
WORKDIR /app
|
||||
|
||||
# Instalar dependencias necesarias
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
bash \
|
||||
curl \
|
||||
gnupg \
|
||||
apt-transport-https \
|
||||
ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
|
||||
|
||||
# Descargar e instalar code-server
|
||||
RUN curl -sSL https://code-server.dev/install.sh | sh || echo "Error al instalar code-server" && \
|
||||
which code-server || echo "code-server no encontrado" && \
|
||||
code-server --version || echo "Error al obtener la versión de code-server"
|
||||
|
||||
|
||||
# Exponer el puerto por defecto de code-server
|
||||
EXPOSE 8080
|
||||
|
||||
# Definir el usuario y grupo de trabajo
|
||||
USER root
|
||||
|
||||
# Comando para iniciar code-server como root
|
||||
ENTRYPOINT ["/bin/bash", "-c", "code-server /app --bind-addr 0.0.0.0:8080 --auth none -vvv"]
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
# Obtener el ID del contenedor actual
|
||||
cat /proc/self/cgroup | grep ":cpu:" | sed 's/.*\///' | head -n 1 | cut -c1-12
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Lista de extensiones a instalar
|
||||
EXTENSIONES=(
|
||||
"ms-python.python"
|
||||
"ms-python.vscode-pylance"
|
||||
"ms-toolsai.jupyter"
|
||||
"ms-toolsai.jupyter-keymap"
|
||||
"ms-toolsai.jupyter-renderers"
|
||||
"ms-toolsai.vscode-jupyter-cell-tags"
|
||||
"ms-toolsai.vscode-jupyter-slideshow"
|
||||
)
|
||||
|
||||
# Función para instalar extensiones
|
||||
instalar_extensiones() {
|
||||
for EXT in "${EXTENSIONES[@]}"; do
|
||||
echo "Instalando $EXT..."
|
||||
code --install-extension "$EXT"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ $EXT instalado correctamente."
|
||||
else
|
||||
echo "❌ Error al instalar $EXT."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Ejecutar la instalación
|
||||
instalar_extensiones
|
||||
echo "🚀 ¡Instalación completada!"
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Actualizar repositorios
|
||||
echo "Actualizando repositorios..."
|
||||
apt-get update
|
||||
|
||||
# Instalar compiladores y herramientas necesarias
|
||||
echo "Instalando gcc, make y otras dependencias..."
|
||||
apt-get install -y gcc make build-essential linux-headers-$(uname -r) python3-dev
|
||||
|
||||
# Instalar Python 3, pip y virtualenv
|
||||
echo "Instalando Python 3, pip y virtualenv..."
|
||||
apt-get install -y python3 python3-pip python3-venv
|
||||
|
||||
# Crear alias para 'python' si no existe
|
||||
if ! command -v python &> /dev/null; then
|
||||
echo "Creando alias para 'python'..."
|
||||
ln -s /usr/bin/python3 /usr/bin/python
|
||||
fi
|
||||
|
||||
# Actualizar pip a la última versión globalmente
|
||||
echo "Actualizando pip globalmente..."
|
||||
python3 -m pip install --upgrade pip
|
||||
|
||||
# Instalar wheel para facilitar la instalación de paquetes compilados
|
||||
echo "Instalando wheel globalmente..."
|
||||
python3 -m pip install wheel
|
||||
|
||||
# Instalar Jupyter y psutil globalmente
|
||||
echo "Instalando Jupyter Notebook y psutil globalmente..."
|
||||
python3 -m pip install jupyter psutil
|
||||
|
||||
# Crear un perfil de configuración por defecto para Jupyter
|
||||
echo "Creando configuración por defecto para Jupyter..."
|
||||
jupyter notebook --generate-config
|
||||
|
||||
# Añadir configuración para ejecutar Jupyter sin token en localhost
|
||||
CONFIG_FILE=$(jupyter --config-dir)/jupyter_notebook_config.py
|
||||
echo "c.NotebookApp.ip = '0.0.0.0'" >> $CONFIG_FILE
|
||||
echo "c.NotebookApp.open_browser = False" >> $CONFIG_FILE
|
||||
echo "c.NotebookApp.token = ''" >> $CONFIG_FILE
|
||||
echo "Configuración creada en $CONFIG_FILE"
|
||||
|
||||
# Verificar la instalación
|
||||
echo "Verificando la instalación..."
|
||||
jupyter --version
|
||||
|
||||
echo "Instalación completada exitosamente."
|
||||
echo "Para iniciar Jupyter, ejecuta: jupyter notebook --allow-root"
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
# 🛠 Actualizar repositorios
|
||||
echo "Actualizando repositorios..."
|
||||
apt-get update
|
||||
|
||||
# 🛠 Instalar Node.js, NPM, y dependencias necesarias si no están instalados
|
||||
echo "Instalando Node.js, NPM y dependencias necesarias..."
|
||||
apt-get install -y curl python3 make g++ git libc-dev bash
|
||||
|
||||
# 🛠 Instalar n (gestor de versiones de Node.js) globalmente
|
||||
echo "Instalando el gestor de versiones 'n' para Node.js..."
|
||||
curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o /usr/local/bin/n
|
||||
chmod +x /usr/local/bin/n
|
||||
|
||||
# 🛠 Eliminar versiones conflictivas de Node.js y NPM
|
||||
echo "Eliminando binarios conflictivos..."
|
||||
rm -f /usr/local/bin/node || true
|
||||
rm -f /usr/local/bin/npm || true
|
||||
rm -f /usr/local/bin/npx || true
|
||||
|
||||
# 🛠 Crear directorio para versiones globales de Node.js si no existe
|
||||
mkdir -p /usr/local/n
|
||||
chown -R $(whoami) /usr/local/n
|
||||
export N_PREFIX=/usr/local/n
|
||||
|
||||
# 🛠 Agregar N_PREFIX al PATH si no está
|
||||
if ! grep -q "/usr/local/n/bin" <<< "$PATH"; then
|
||||
export PATH="/usr/local/n/bin:$PATH"
|
||||
echo 'export PATH="/usr/local/n/bin:$PATH"' >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
fi
|
||||
|
||||
# 🛠 Función para configurar la versión de Node.js
|
||||
setup_node_version() {
|
||||
local VERSION=$1
|
||||
echo "Instalando Node.js v$VERSION..."
|
||||
n $VERSION
|
||||
|
||||
# 🛠 Crear enlaces simbólicos globales
|
||||
ln -sf /usr/local/n/bin/node /usr/local/bin/node
|
||||
ln -sf /usr/local/n/bin/npm /usr/local/bin/npm
|
||||
ln -sf /usr/local/n/bin/npx /usr/local/bin/npx
|
||||
|
||||
# 🛠 Actualizar el PATH y limpiar caché de comandos
|
||||
export PATH="/usr/local/n/bin:$PATH"
|
||||
hash -r
|
||||
|
||||
# 🛠 Mostrar la versión instalada
|
||||
echo "Node.js actualizado a:"
|
||||
node -v
|
||||
npm -v
|
||||
}
|
||||
|
||||
# 🛠 Preguntar al usuario qué versión quiere instalar
|
||||
echo "¿Qué versión de Node.js deseas instalar? (Ejemplo: 20)"
|
||||
read -r NODE_VERSION
|
||||
|
||||
# 🛠 Ejecutar la instalación de la versión solicitada
|
||||
setup_node_version $NODE_VERSION
|
||||
|
||||
# 🛠 Instrucciones para cambiar de versión rápidamente
|
||||
cat << EOF
|
||||
|
||||
¡Node.js v$NODE_VERSION instalado correctamente! 🎉
|
||||
|
||||
Para cambiar de versión en el futuro, usa:
|
||||
n <versión> # Ejemplo: n 18
|
||||
|
||||
Para listar versiones disponibles:
|
||||
n ls-remote
|
||||
|
||||
Para listar versiones instaladas localmente:
|
||||
n ls
|
||||
|
||||
Para borrar una versión específica:
|
||||
n rm <versión> # Ejemplo: n rm 18
|
||||
|
||||
¡Disfruta usando Node.js con n! 🚀
|
||||
EOF
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Preguntar la versión de Python que se desea instalar
|
||||
read -p "Ingresa la versión de Python que deseas establecer como global (por ejemplo, 3.11.2 o 3.8.9): " PYTHON_VERSION
|
||||
|
||||
# Validar el formato de la versión ingresada (más permisivo)
|
||||
if [[ ! $PYTHON_VERSION =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?([a-zA-Z0-9]+)?$ ]]; then
|
||||
echo "❌ Formato inválido. Asegúrate de ingresar una versión válida (por ejemplo, 3.11.2, 3.8.9, 3.8.9b1)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Comprobar si pyenv está instalado
|
||||
if ! command -v pyenv &> /dev/null; then
|
||||
echo "pyenv no está instalado. Procediendo a instalarlo..."
|
||||
|
||||
# Instalar dependencias para pyenv
|
||||
apt-get update
|
||||
apt-get install -y curl git build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev libffi-dev liblzma-dev
|
||||
|
||||
# Instalar pyenv
|
||||
curl https://pyenv.run | bash
|
||||
|
||||
# Configurar pyenv en el shell actual
|
||||
export PATH="$HOME/.pyenv/bin:$PATH"
|
||||
eval "$(pyenv init --path)"
|
||||
eval "$(pyenv init -)"
|
||||
eval "$(pyenv virtualenv-init -)"
|
||||
|
||||
# Agregar pyenv al bashrc para futuros shells
|
||||
echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
|
||||
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
|
||||
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
|
||||
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
|
||||
fi
|
||||
|
||||
# Verificar si la versión de Python ya está instalada con pyenv
|
||||
if pyenv versions --bare | grep -q "^$PYTHON_VERSION$"; then
|
||||
echo "✅ Python $PYTHON_VERSION ya está instalado."
|
||||
else
|
||||
# Instalar la versión solicitada de Python
|
||||
echo "Instalando Python $PYTHON_VERSION con pyenv..."
|
||||
pyenv install $PYTHON_VERSION
|
||||
|
||||
# Comprobar si la instalación fue exitosa
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "❌ Error durante la instalación de Python $PYTHON_VERSION."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# Establecer la versión global de Python con pyenv
|
||||
echo "Configurando Python $PYTHON_VERSION como versión global..."
|
||||
pyenv global $PYTHON_VERSION
|
||||
|
||||
# Actualizar pip a la última versión
|
||||
echo "Actualizando pip..."
|
||||
pip install --upgrade pip
|
||||
|
||||
# Verificar la instalación
|
||||
echo "Verificando la instalación..."
|
||||
python --version
|
||||
pip --version
|
||||
|
||||
# Recargar .bashrc para aplicar los cambios
|
||||
echo "Recargando .bashrc para aplicar los cambios de pyenv..."
|
||||
source ~/.bashrc
|
||||
|
||||
echo "✅ Python $PYTHON_VERSION configurado como versión global exitosamente."
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Actualizar repositorios
|
||||
echo "Actualizando repositorios..."
|
||||
apt-get update
|
||||
|
||||
# Instalar Python 3 y pip
|
||||
echo "Instalando Python 3 y pip..."
|
||||
apt-get install -y python3 python3-pip
|
||||
|
||||
# Crear alias para 'python' si no existe
|
||||
if ! command -v python &> /dev/null
|
||||
then
|
||||
echo "Creando alias para 'python'..."
|
||||
ln -s /usr/bin/python3 /usr/bin/python
|
||||
fi
|
||||
|
||||
# Actualizar pip a la última versión
|
||||
echo "Actualizando pip..."
|
||||
python3 -m pip install --upgrade pip --break-system-packages
|
||||
|
||||
# Verificar la instalación
|
||||
echo "Verificando la instalación..."
|
||||
python --version
|
||||
pip --version
|
||||
|
||||
echo "Instalación completada exitosamente."
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Actualiza los repositorios y asegura que curl esté instalado
|
||||
apt-get update
|
||||
apt-get install -y curl
|
||||
|
||||
# Verifica las versiones instaladas
|
||||
echo "Node.js version:"
|
||||
node -v
|
||||
echo "npm version:"
|
||||
npm -v
|
||||
|
||||
# Crea un directorio para el proyecto
|
||||
mkdir "frontend"
|
||||
cd "frontend"
|
||||
|
||||
# Inicializa un nuevo proyecto React
|
||||
npx create-react-app .
|
||||
|
||||
# Instala Material-UI y sus dependencias
|
||||
npm install @mui/material @emotion/react @emotion/styled
|
||||
|
||||
# Inicia el servidor de desarrollo
|
||||
npm start
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Actualizar repositorios
|
||||
echo "Actualizando repositorios..."
|
||||
apt-get update
|
||||
|
||||
# Instalar venv si no está disponible
|
||||
if ! python3 -m venv --help &> /dev/null; then
|
||||
echo "Instalando venv..."
|
||||
apt-get install -y python3-venv
|
||||
fi
|
||||
|
||||
# Crear un entorno virtual llamado 'venv'
|
||||
echo "Creando entorno virtual 'venv'..."
|
||||
python3 -m venv /app/venv
|
||||
|
||||
echo "Entorno virtual 'venv' creado exitosamente."
|
||||
@@ -0,0 +1,618 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# code-server's automatic install script.
|
||||
# See https://coder.com/docs/code-server/latest/install
|
||||
|
||||
usage() {
|
||||
arg0="$0"
|
||||
if [ "$0" = sh ]; then
|
||||
arg0="curl -fsSL https://code-server.dev/install.sh | sh -s --"
|
||||
else
|
||||
not_curl_usage="The latest script is available at https://code-server.dev/install.sh
|
||||
"
|
||||
fi
|
||||
|
||||
cath << EOF
|
||||
Installs code-server.
|
||||
It tries to use the system package manager if possible.
|
||||
After successful installation it explains how to start using code-server.
|
||||
|
||||
Pass in user@host to install code-server on user@host over ssh.
|
||||
The remote host must have internet access.
|
||||
${not_curl_usage-}
|
||||
Usage:
|
||||
|
||||
$arg0 [--dry-run] [--version X.X.X] [--edge] [--method detect] \
|
||||
[--prefix ~/.local] [--rsh ssh] [user@host]
|
||||
|
||||
--dry-run
|
||||
Echo the commands for the install process without running them.
|
||||
|
||||
--version X.X.X
|
||||
Install a specific version instead of the latest.
|
||||
|
||||
--edge
|
||||
Install the latest edge version instead of the latest stable version.
|
||||
|
||||
--method [detect | standalone]
|
||||
Choose the installation method. Defaults to detect.
|
||||
- detect detects the system package manager and tries to use it.
|
||||
Full reference on the process is further below.
|
||||
- standalone installs a standalone release archive into ~/.local
|
||||
Add ~/.local/bin to your \$PATH to use it.
|
||||
|
||||
--prefix <dir>
|
||||
Sets the prefix used by standalone release archives. Defaults to ~/.local
|
||||
The release is unarchived into ~/.local/lib/code-server-X.X.X
|
||||
and the binary symlinked into ~/.local/bin/code-server
|
||||
To install system wide pass --prefix=/usr/local
|
||||
|
||||
--rsh <bin>
|
||||
Specifies the remote shell for remote installation. Defaults to ssh.
|
||||
|
||||
The detection method works as follows:
|
||||
- Debian, Ubuntu, Raspbian: install the deb package from GitHub.
|
||||
- Fedora, CentOS, RHEL, openSUSE: install the rpm package from GitHub.
|
||||
- Arch Linux: install from the AUR (which pulls releases from GitHub).
|
||||
- FreeBSD, Alpine: install from npm.
|
||||
- macOS: install using Homebrew if installed otherwise install from GitHub.
|
||||
- All others: install the release from GitHub.
|
||||
|
||||
We only build releases on GitHub for amd64 and arm64 on Linux and amd64 for
|
||||
macOS. When the detection method tries to pull a release from GitHub it will
|
||||
fall back to installing from npm when there is no matching release for the
|
||||
system's operating system and architecture.
|
||||
|
||||
The standalone method will force installion using GitHub releases. It will not
|
||||
fall back to npm so on architectures without pre-built releases this will error.
|
||||
|
||||
The installer will cache all downloaded assets into ~/.cache/code-server
|
||||
|
||||
More installation docs are at https://coder.com/docs/code-server/latest/install
|
||||
EOF
|
||||
}
|
||||
|
||||
echo_latest_version() {
|
||||
if [ "${EDGE-}" ]; then
|
||||
version="$(curl -fsSL https://api.github.com/repos/coder/code-server/releases | awk 'match($0,/.*"html_url": "(.*\/releases\/tag\/.*)".*/)' | head -n 1 | awk -F '"' '{print $4}')"
|
||||
else
|
||||
# https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860
|
||||
version="$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/coder/code-server/releases/latest)"
|
||||
fi
|
||||
version="${version#https://github.com/coder/code-server/releases/tag/}"
|
||||
version="${version#v}"
|
||||
echo "$version"
|
||||
}
|
||||
|
||||
echo_npm_postinstall() {
|
||||
echoh
|
||||
cath << EOF
|
||||
npm package has been installed.
|
||||
|
||||
Extend your path to use code-server:
|
||||
PATH="$NPM_BIN_DIR:\$PATH"
|
||||
Then run with:
|
||||
code-server
|
||||
EOF
|
||||
}
|
||||
|
||||
echo_standalone_postinstall() {
|
||||
echoh
|
||||
cath << EOF
|
||||
Standalone release has been installed into $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION
|
||||
|
||||
Extend your path to use code-server:
|
||||
PATH="$STANDALONE_INSTALL_PREFIX/bin:\$PATH"
|
||||
Then run with:
|
||||
code-server
|
||||
EOF
|
||||
}
|
||||
|
||||
echo_brew_postinstall() {
|
||||
echoh
|
||||
cath << EOF
|
||||
Brew release has been installed.
|
||||
|
||||
Run with:
|
||||
code-server
|
||||
EOF
|
||||
}
|
||||
|
||||
echo_systemd_postinstall() {
|
||||
echoh
|
||||
cath << EOF
|
||||
$1 package has been installed.
|
||||
|
||||
To have systemd start code-server now and restart on boot:
|
||||
sudo systemctl enable --now code-server@\$USER
|
||||
Or, if you don't want/need a background service you can run:
|
||||
code-server
|
||||
EOF
|
||||
}
|
||||
|
||||
echo_coder_postinstall() {
|
||||
echoh
|
||||
echoh "Deploy code-server for your team with Coder: https://github.com/coder/coder"
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ "${TRACE-}" ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
unset \
|
||||
DRY_RUN \
|
||||
METHOD \
|
||||
OPTIONAL \
|
||||
ALL_FLAGS \
|
||||
RSH_ARGS \
|
||||
EDGE \
|
||||
RSH
|
||||
|
||||
ALL_FLAGS=""
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-*)
|
||||
ALL_FLAGS="${ALL_FLAGS} $1"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
;;
|
||||
--method)
|
||||
METHOD="$(parse_arg "$@")"
|
||||
shift
|
||||
;;
|
||||
--method=*)
|
||||
METHOD="$(parse_arg "$@")"
|
||||
;;
|
||||
--prefix)
|
||||
STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")"
|
||||
shift
|
||||
;;
|
||||
--prefix=*)
|
||||
STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")"
|
||||
;;
|
||||
--version)
|
||||
VERSION="$(parse_arg "$@")"
|
||||
shift
|
||||
;;
|
||||
--version=*)
|
||||
VERSION="$(parse_arg "$@")"
|
||||
;;
|
||||
--edge)
|
||||
EDGE=1
|
||||
;;
|
||||
--rsh)
|
||||
RSH="$(parse_arg "$@")"
|
||||
shift
|
||||
;;
|
||||
--rsh=*)
|
||||
RSH="$(parse_arg "$@")"
|
||||
;;
|
||||
-h | --h | -help | --help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
# We remove the -- added above.
|
||||
ALL_FLAGS="${ALL_FLAGS% --}"
|
||||
RSH_ARGS="$*"
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echoerr "Unknown flag $1"
|
||||
echoerr "Run with --help to see usage."
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
RSH_ARGS="$*"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "${RSH_ARGS-}" ]; then
|
||||
RSH="${RSH-ssh}"
|
||||
echoh "Installing remotely with $RSH $RSH_ARGS"
|
||||
curl -fsSL https://code-server.dev/install.sh | prefix "$RSH_ARGS" "$RSH" "$RSH_ARGS" sh -s -- "$ALL_FLAGS"
|
||||
return
|
||||
fi
|
||||
|
||||
METHOD="${METHOD-detect}"
|
||||
if [ "$METHOD" != detect ] && [ "$METHOD" != standalone ]; then
|
||||
echoerr "Unknown install method \"$METHOD\""
|
||||
echoerr "Run with --help to see usage."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# These are used by the various install_* functions that make use of GitHub
|
||||
# releases in order to download and unpack the right release.
|
||||
CACHE_DIR=$(echo_cache_dir)
|
||||
STANDALONE_INSTALL_PREFIX=${STANDALONE_INSTALL_PREFIX:-$HOME/.local}
|
||||
VERSION=${VERSION:-$(echo_latest_version)}
|
||||
# These can be overridden for testing but shouldn't normally be used as it can
|
||||
# result in a broken code-server.
|
||||
OS=${OS:-$(os)}
|
||||
ARCH=${ARCH:-$(arch)}
|
||||
|
||||
distro_name
|
||||
|
||||
# Standalone installs by pulling pre-built releases from GitHub.
|
||||
if [ "$METHOD" = standalone ]; then
|
||||
if has_standalone; then
|
||||
install_standalone
|
||||
echo_coder_postinstall
|
||||
exit 0
|
||||
else
|
||||
echoerr "There are no standalone releases for $ARCH"
|
||||
echoerr "Please try again without '--method standalone'"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# DISTRO can be overridden for testing but shouldn't normally be used as it
|
||||
# can result in a broken code-server.
|
||||
DISTRO=${DISTRO:-$(distro)}
|
||||
|
||||
case $DISTRO in
|
||||
# macOS uses brew when available and falls back to standalone. We only have
|
||||
# amd64 for macOS so for anything else use npm.
|
||||
macos)
|
||||
BREW_PATH="${BREW_PATH-brew}"
|
||||
if command_exists "$BREW_PATH"; then
|
||||
install_brew
|
||||
else
|
||||
echoh "Homebrew not installed."
|
||||
echoh "Falling back to standalone installation."
|
||||
npm_fallback install_standalone
|
||||
fi
|
||||
;;
|
||||
# The .deb and .rpm files are pulled from GitHub and we only have amd64 and
|
||||
# arm64 there and need to fall back to npm otherwise.
|
||||
debian) npm_fallback install_deb ;;
|
||||
fedora | opensuse) npm_fallback install_rpm ;;
|
||||
# Arch uses the AUR package which only supports amd64 and arm64 since it
|
||||
# pulls releases from GitHub so we need to fall back to npm.
|
||||
arch) npm_fallback install_aur ;;
|
||||
# We don't have GitHub releases that work on Alpine or FreeBSD so we have no
|
||||
# choice but to use npm here.
|
||||
alpine | freebsd) install_npm ;;
|
||||
# For anything else we'll try to install standalone but fall back to npm if
|
||||
# we don't have releases for the architecture.
|
||||
*)
|
||||
echoh "Unsupported package manager."
|
||||
echoh "Falling back to standalone installation."
|
||||
npm_fallback install_standalone
|
||||
;;
|
||||
esac
|
||||
|
||||
echo_coder_postinstall
|
||||
}
|
||||
|
||||
parse_arg() {
|
||||
case "$1" in
|
||||
*=*)
|
||||
# Remove everything after first equal sign.
|
||||
opt="${1%%=*}"
|
||||
# Remove everything before first equal sign.
|
||||
optarg="${1#*=}"
|
||||
if [ ! "$optarg" ] && [ ! "${OPTIONAL-}" ]; then
|
||||
echoerr "$opt requires an argument"
|
||||
echoerr "Run with --help to see usage."
|
||||
exit 1
|
||||
fi
|
||||
echo "$optarg"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${2-}" in
|
||||
"" | -*)
|
||||
if [ ! "${OPTIONAL-}" ]; then
|
||||
echoerr "$1 requires an argument"
|
||||
echoerr "Run with --help to see usage."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "$2"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
fetch() {
|
||||
URL="$1"
|
||||
FILE="$2"
|
||||
|
||||
if [ -e "$FILE" ]; then
|
||||
echoh "+ Reusing $FILE"
|
||||
return
|
||||
fi
|
||||
|
||||
sh_c mkdir -p "$CACHE_DIR"
|
||||
sh_c curl \
|
||||
-#fL \
|
||||
-o "$FILE.incomplete" \
|
||||
-C - \
|
||||
"$URL"
|
||||
sh_c mv "$FILE.incomplete" "$FILE"
|
||||
}
|
||||
|
||||
install_brew() {
|
||||
echoh "Installing latest from Homebrew."
|
||||
echoh
|
||||
|
||||
sh_c "$BREW_PATH" install code-server
|
||||
|
||||
echo_brew_postinstall
|
||||
}
|
||||
|
||||
install_deb() {
|
||||
echoh "Installing v$VERSION of the $ARCH deb package from GitHub."
|
||||
echoh
|
||||
|
||||
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_$ARCH.deb" \
|
||||
"$CACHE_DIR/code-server_${VERSION}_$ARCH.deb"
|
||||
sudo_sh_c dpkg -i "$CACHE_DIR/code-server_${VERSION}_$ARCH.deb"
|
||||
|
||||
echo_systemd_postinstall deb
|
||||
}
|
||||
|
||||
install_rpm() {
|
||||
echoh "Installing v$VERSION of the $ARCH rpm package from GitHub."
|
||||
echoh
|
||||
|
||||
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$ARCH.rpm" \
|
||||
"$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
|
||||
sudo_sh_c rpm -U "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
|
||||
|
||||
echo_systemd_postinstall rpm
|
||||
}
|
||||
|
||||
install_aur() {
|
||||
echoh "Installing latest from the AUR."
|
||||
echoh
|
||||
|
||||
sh_c mkdir -p "$CACHE_DIR/code-server-aur"
|
||||
sh_c "curl -#fsSL https://aur.archlinux.org/cgit/aur.git/snapshot/code-server.tar.gz | tar -xzC $CACHE_DIR/code-server-aur --strip-components 1"
|
||||
echo "+ cd $CACHE_DIR/code-server-aur"
|
||||
if [ ! "${DRY_RUN-}" ]; then
|
||||
cd "$CACHE_DIR/code-server-aur"
|
||||
fi
|
||||
sh_c makepkg -si --noconfirm
|
||||
|
||||
echo_systemd_postinstall AUR
|
||||
}
|
||||
|
||||
install_standalone() {
|
||||
echoh "Installing v$VERSION of the $ARCH release from GitHub."
|
||||
echoh
|
||||
|
||||
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$OS-$ARCH.tar.gz" \
|
||||
"$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz"
|
||||
|
||||
# -w only works if the directory exists so try creating it first. If this
|
||||
# fails we can ignore the error as the -w check will then swap us to sudo.
|
||||
sh_c mkdir -p "$STANDALONE_INSTALL_PREFIX" 2> /dev/null || true
|
||||
|
||||
sh_c="sh_c"
|
||||
if [ ! -w "$STANDALONE_INSTALL_PREFIX" ]; then
|
||||
sh_c="sudo_sh_c"
|
||||
fi
|
||||
|
||||
if [ -e "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" ]; then
|
||||
echoh
|
||||
echoh "code-server-$VERSION is already installed at $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION"
|
||||
echoh "Remove it to reinstall."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
"$sh_c" mkdir -p "$STANDALONE_INSTALL_PREFIX/lib" "$STANDALONE_INSTALL_PREFIX/bin"
|
||||
"$sh_c" tar -C "$STANDALONE_INSTALL_PREFIX/lib" -xzf "$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz"
|
||||
"$sh_c" mv -f "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION-$OS-$ARCH" "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION"
|
||||
"$sh_c" ln -fs "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION/bin/code-server" "$STANDALONE_INSTALL_PREFIX/bin/code-server"
|
||||
|
||||
echo_standalone_postinstall
|
||||
}
|
||||
|
||||
install_npm() {
|
||||
echoh "Installing v$VERSION from npm."
|
||||
echoh
|
||||
|
||||
NPM_PATH="${YARN_PATH-npm}"
|
||||
|
||||
if command_exists "$NPM_PATH"; then
|
||||
sh_c="sh_c"
|
||||
if [ ! "${DRY_RUN-}" ] && [ ! -w "$(NPM_PATH config get prefix)" ]; then
|
||||
sh_c="sudo_sh_c"
|
||||
fi
|
||||
echoh "Installing with npm."
|
||||
echoh
|
||||
"$sh_c" "$NPM_PATH" install -g "code-server@$VERSION" --unsafe-perm
|
||||
NPM_BIN_DIR="\$($NPM_PATH bin -g)" echo_npm_postinstall
|
||||
return
|
||||
fi
|
||||
echoerr "Please install npm to install code-server!"
|
||||
echoerr "You will need at least node v20 and a few C dependencies."
|
||||
echoerr "See the docs https://coder.com/docs/code-server/latest/install#npm"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Run $1 if we have a standalone otherwise run install_npm.
|
||||
npm_fallback() {
|
||||
if has_standalone; then
|
||||
$1
|
||||
else
|
||||
echoh "No standalone releases for $ARCH."
|
||||
echoh "Falling back to installation from npm."
|
||||
install_npm
|
||||
fi
|
||||
}
|
||||
|
||||
# Determine if we have standalone releases on GitHub for the system's arch.
|
||||
has_standalone() {
|
||||
case $ARCH in
|
||||
arm64) return 0 ;;
|
||||
# We only have arm64 for macOS.
|
||||
amd64)
|
||||
[ "$(distro)" != macos ]
|
||||
return
|
||||
;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
os() {
|
||||
uname="$(uname)"
|
||||
case $uname in
|
||||
Linux) echo linux ;;
|
||||
Darwin) echo macos ;;
|
||||
FreeBSD) echo freebsd ;;
|
||||
*) echo "$uname" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Print the detected Linux distro, otherwise print the OS name.
|
||||
#
|
||||
# Example outputs:
|
||||
# - macos -> macos
|
||||
# - freebsd -> freebsd
|
||||
# - ubuntu, raspbian, debian ... -> debian
|
||||
# - amzn, centos, rhel, fedora, ... -> fedora
|
||||
# - opensuse-{leap,tumbleweed} -> opensuse
|
||||
# - alpine -> alpine
|
||||
# - arch, manjaro, endeavouros, ... -> arch
|
||||
#
|
||||
# Inspired by https://github.com/docker/docker-install/blob/26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c/install.sh#L111-L120.
|
||||
distro() {
|
||||
if [ "$OS" = "macos" ] || [ "$OS" = "freebsd" ]; then
|
||||
echo "$OS"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -f /etc/os-release ]; then
|
||||
(
|
||||
. /etc/os-release
|
||||
if [ "${ID_LIKE-}" ]; then
|
||||
for id_like in $ID_LIKE; do
|
||||
case "$id_like" in debian | fedora | opensuse | arch)
|
||||
echo "$id_like"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
echo "$ID"
|
||||
)
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
# Print a human-readable name for the OS/distro.
|
||||
distro_name() {
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
echo "macOS v$(sw_vers -productVersion)"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -f /etc/os-release ]; then
|
||||
(
|
||||
. /etc/os-release
|
||||
echo "$PRETTY_NAME"
|
||||
)
|
||||
return
|
||||
fi
|
||||
|
||||
# Prints something like: Linux 4.19.0-9-amd64
|
||||
uname -sr
|
||||
}
|
||||
|
||||
arch() {
|
||||
uname_m=$(uname -m)
|
||||
case $uname_m in
|
||||
aarch64) echo arm64 ;;
|
||||
x86_64) echo amd64 ;;
|
||||
*) echo "$uname_m" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
command_exists() {
|
||||
if [ ! "$1" ]; then return 1; fi
|
||||
command -v "$@" > /dev/null
|
||||
}
|
||||
|
||||
sh_c() {
|
||||
echoh "+ $*"
|
||||
if [ ! "${DRY_RUN-}" ]; then
|
||||
sh -c "$*"
|
||||
fi
|
||||
}
|
||||
|
||||
sudo_sh_c() {
|
||||
if [ "$(id -u)" = 0 ]; then
|
||||
sh_c "$@"
|
||||
elif command_exists doas; then
|
||||
sh_c "doas $*"
|
||||
elif command_exists sudo; then
|
||||
sh_c "sudo $*"
|
||||
elif command_exists su; then
|
||||
sh_c "su root -c '$*'"
|
||||
else
|
||||
echoh
|
||||
echoerr "This script needs to run the following command as root."
|
||||
echoerr " $*"
|
||||
echoerr "Please install doas, sudo, or su."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
echo_cache_dir() {
|
||||
if [ "${XDG_CACHE_HOME-}" ]; then
|
||||
echo "$XDG_CACHE_HOME/code-server"
|
||||
elif [ "${HOME-}" ]; then
|
||||
echo "$HOME/.cache/code-server"
|
||||
else
|
||||
echo "/tmp/code-server-cache"
|
||||
fi
|
||||
}
|
||||
|
||||
echoh() {
|
||||
echo "$@" | humanpath
|
||||
}
|
||||
|
||||
cath() {
|
||||
humanpath
|
||||
}
|
||||
|
||||
echoerr() {
|
||||
echoh "$@" >&2
|
||||
}
|
||||
|
||||
# humanpath replaces all occurrences of " $HOME" with " ~"
|
||||
# and all occurrences of '"$HOME' with the literal '"$HOME'.
|
||||
humanpath() {
|
||||
sed "s# $HOME# ~#g; s#\"$HOME#\"\$HOME#g"
|
||||
}
|
||||
|
||||
# We need to make sure we exit with a non zero exit if the command fails.
|
||||
# /bin/sh does not support -o pipefail unfortunately.
|
||||
prefix() {
|
||||
PREFIX="$1"
|
||||
shift
|
||||
fifo="$(mktemp -d)/fifo"
|
||||
mkfifo "$fifo"
|
||||
sed -e "s#^#$PREFIX: #" "$fifo" &
|
||||
"$@" > "$fifo" 2>&1
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -0,0 +1,80 @@
|
||||
import os
|
||||
import uuid
|
||||
import shutil
|
||||
import json
|
||||
import subprocess
|
||||
import hashlib
|
||||
from datetime import datetime
|
||||
|
||||
# Archivo JSON para guardar los datos de los contenedores
|
||||
CONTAINER_DATA_FILE = 'containers.json'
|
||||
# Nombre y etiqueta para la imagen base
|
||||
BASE_IMAGE_TAG = 'alpine_vscode:latest'
|
||||
|
||||
CONTENEDOR_IDENTIFICADOR = "easily-sound-ant"
|
||||
|
||||
# -------------------------------
|
||||
# Función: Eliminar un contenedor por ID o nombre y actualizar el JSON
|
||||
# -------------------------------
|
||||
def delete_container(identifier):
|
||||
if not os.path.exists(CONTAINER_DATA_FILE):
|
||||
print("❌ No hay archivo JSON de contenedores.")
|
||||
return
|
||||
|
||||
with open(CONTAINER_DATA_FILE, 'r') as file:
|
||||
containers = json.load(file)
|
||||
|
||||
# Determinar si el identificador es un ID o un nombre
|
||||
container = next((c for c in containers if c['id'] == identifier or c['name'] == identifier), None)
|
||||
if not container:
|
||||
print(f"❌ No se encontró ningún contenedor con ID o nombre: {identifier} en el JSON.")
|
||||
return
|
||||
|
||||
try:
|
||||
# Comprobar si el contenedor existe realmente en Docker
|
||||
result = subprocess.getoutput(f"docker ps -a -q -f id={container['id']}")
|
||||
if not result:
|
||||
print(f"⚠️ El contenedor {container['name']} ya no existe en Docker. Eliminando del JSON...")
|
||||
else:
|
||||
# Eliminar el contenedor y su red asociada
|
||||
print(f"➤ Eliminando contenedor: {container['name']} con ID: {container['id']}")
|
||||
os.system(f"docker rm -f {container['id']}")
|
||||
print(f"➤ Eliminando red: {container['network']}")
|
||||
os.system(f"docker network rm {container['network']}")
|
||||
|
||||
# Actualizar el JSON excluyendo el contenedor eliminado
|
||||
containers = [c for c in containers if c['id'] != container['id']]
|
||||
with open(CONTAINER_DATA_FILE, 'w') as file:
|
||||
json.dump(containers, file, indent=4)
|
||||
|
||||
print(f"✔ Contenedor {container['name']} eliminado correctamente.")
|
||||
except Exception as e:
|
||||
print(f"❌ Error eliminando el contenedor {container['name']}: {e}")
|
||||
|
||||
# -------------------------------
|
||||
# Función: Limpiar imágenes huérfanas
|
||||
# -------------------------------
|
||||
def clean_unused_images():
|
||||
print("➤ Eliminando imágenes huérfanas...")
|
||||
os.system('docker image prune -f')
|
||||
|
||||
# -------------------------------
|
||||
# Función: Limpiar redes huérfanas
|
||||
# -------------------------------
|
||||
def clean_unused_networks():
|
||||
print("➤ Eliminando redes huérfanas...")
|
||||
os.system('docker network prune -f')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
identifier = CONTENEDOR_IDENTIFICADOR
|
||||
|
||||
if identifier:
|
||||
delete_container(identifier)
|
||||
|
||||
# Limpiar imágenes y redes huérfanas
|
||||
clean_unused_images()
|
||||
clean_unused_networks()
|
||||
|
||||
else:
|
||||
print("❌ No se ingresó ningún ID o nombre.")
|
||||
@@ -0,0 +1,89 @@
|
||||
import os
|
||||
import uuid
|
||||
import shutil
|
||||
import json
|
||||
import subprocess
|
||||
import hashlib
|
||||
from datetime import datetime
|
||||
|
||||
# Archivo JSON para guardar los datos de los contenedores
|
||||
CONTAINER_DATA_FILE = 'containers.json'
|
||||
# Nombre y etiqueta para la imagen base
|
||||
BASE_IMAGE_TAG = 'alpine_vscode:latest'
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Eliminar todos los contenedores listados en el JSON
|
||||
# -------------------------------
|
||||
def delete_all_containers():
|
||||
if not os.path.exists(CONTAINER_DATA_FILE):
|
||||
print("❌ No hay contenedores para eliminar.")
|
||||
return
|
||||
|
||||
with open(CONTAINER_DATA_FILE, 'r') as file:
|
||||
containers = json.load(file)
|
||||
|
||||
if not containers:
|
||||
print("❌ No hay contenedores listados en el archivo JSON.")
|
||||
return
|
||||
|
||||
# Lista para los contenedores que no pudieron eliminarse
|
||||
remaining_containers = []
|
||||
|
||||
# Eliminar contenedores y redes
|
||||
for container in containers:
|
||||
try:
|
||||
# Comprobar si el contenedor existe realmente
|
||||
result = subprocess.getoutput(f"docker ps -a -q -f id={container['id']}")
|
||||
if not result:
|
||||
print(f"⚠️ El contenedor {container['name']} ya no existe. Eliminando del JSON...")
|
||||
else:
|
||||
print(f"➤ Eliminando contenedor: {container['name']} con ID: {container['id']}")
|
||||
os.system(f"docker rm -f {container['id']}")
|
||||
print(f"➤ Eliminando red: {container['network']}")
|
||||
os.system(f"docker network rm {container['network']}")
|
||||
except Exception as e:
|
||||
print(f"❌ Error eliminando el contenedor {container['name']}: {e}")
|
||||
# Guardar el contenedor en la lista si no se pudo eliminar
|
||||
remaining_containers.append(container)
|
||||
continue
|
||||
|
||||
# Actualizar el archivo JSON solo con los contenedores que no pudieron eliminarse
|
||||
if remaining_containers:
|
||||
with open(CONTAINER_DATA_FILE, 'w') as file:
|
||||
json.dump(remaining_containers, file, indent=4)
|
||||
print("⚠️ Algunos contenedores no pudieron eliminarse y se mantuvieron en el JSON.")
|
||||
else:
|
||||
# Si todos los contenedores fueron eliminados, vaciar el archivo JSON
|
||||
open(CONTAINER_DATA_FILE, 'w').close()
|
||||
print("✔ Todos los contenedores y redes han sido eliminados y el archivo JSON ha sido limpiado.")
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Limpiar imágenes huérfanas
|
||||
# -------------------------------
|
||||
def clean_unused_images():
|
||||
print("➤ Eliminando imágenes huérfanas...")
|
||||
os.system('docker image prune -f')
|
||||
|
||||
# -------------------------------
|
||||
# Función: Limpiar redes huérfanas
|
||||
# -------------------------------
|
||||
def clean_unused_networks():
|
||||
print("➤ Eliminando redes huérfanas...")
|
||||
os.system('docker network prune -f')
|
||||
|
||||
|
||||
##############################################
|
||||
# Ejecución del script
|
||||
##############################################
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# Eliminar todos los contenedores y redes
|
||||
delete_all_containers()
|
||||
|
||||
clean_unused_images()
|
||||
clean_unused_networks()
|
||||
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
import os
|
||||
import uuid
|
||||
import shutil
|
||||
import json
|
||||
import socket
|
||||
import subprocess
|
||||
import petname
|
||||
import hashlib
|
||||
import platform
|
||||
from datetime import datetime
|
||||
|
||||
# Archivo JSON para guardar los datos de los contenedores
|
||||
CONTAINER_DATA_FILE = 'containers.json'
|
||||
# Nombre y etiqueta para la imagen base
|
||||
BASE_IMAGE_TAG = 'debian_vscode:tag'
|
||||
|
||||
#Lita de puertos internos
|
||||
PUERTOS_INTERNOS = [3000, 5000, 8000, 8080, 17000]
|
||||
|
||||
# Numero de conteineres a crear
|
||||
NUM_CONTAINERS = 1
|
||||
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Comprobar si un puerto está libre con nmap
|
||||
# -------------------------------
|
||||
def is_port_available(port):
|
||||
# Ejecuta nmap para comprobar si el puerto está abierto
|
||||
command = f"nmap -p {port} 127.0.0.1"
|
||||
print(f"[INFO] Ejecutando nmap para el puerto {port}...")
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
|
||||
# Muestra el resultado del comando nmap
|
||||
print(f"[DEBUG] Resultado de nmap para el puerto {port}:\n{result.stdout}")
|
||||
|
||||
# Analiza el resultado para ver si el puerto está cerrado
|
||||
if "closed" in result.stdout:
|
||||
return True # Puerto libre
|
||||
else:
|
||||
return False # Puerto ocupado
|
||||
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Ejecutar contenedor y guardar datos
|
||||
# -------------------------------
|
||||
def run_docker_compose(internal_ports=None):
|
||||
# Genera un UUID único
|
||||
unique_uuid = str(uuid.uuid4())
|
||||
# Genera un nombre único para el contenedor
|
||||
uuid_palabras = petname.Generate(3, separator='-')
|
||||
|
||||
|
||||
# Nombres únicos para el servicio, contenedor y la red
|
||||
service_name = f"{uuid_palabras}"
|
||||
container_name = f"{uuid_palabras}"
|
||||
network_name = f"alpine_network_{unique_uuid}"
|
||||
|
||||
# Nombre de la imagen local a usar
|
||||
image_tag = BASE_IMAGE_TAG # Usar la imagen local directamente
|
||||
|
||||
# Nombre del archivo docker-compose nuevo
|
||||
new_docker_compose_file = f'docker-compose-{unique_uuid}.yml'
|
||||
|
||||
try:
|
||||
# Configuración personalizada de puertos
|
||||
ports_mapping = []
|
||||
custom_ports = []
|
||||
host_port = 27000 # Puerto inicial
|
||||
print(f"[INFO] Iniciando la configuración de puertos a partir del puerto {host_port}")
|
||||
|
||||
if internal_ports:
|
||||
for internal_port in internal_ports:
|
||||
print(f"[INFO] Configurando puerto interno: {internal_port}")
|
||||
|
||||
# Buscar el siguiente puerto disponible usando nmap
|
||||
while host_port <= 65000:
|
||||
if is_port_available(host_port):
|
||||
print(f"[INFO] Asignando puerto {host_port} para el puerto interno {internal_port}...")
|
||||
custom_ports.append(f" - \"{host_port}:{internal_port}\"")
|
||||
ports_mapping.append({
|
||||
"host_port": host_port,
|
||||
"internal_port": internal_port
|
||||
})
|
||||
host_port += 1 # Incrementa el puerto para el siguiente uso
|
||||
break
|
||||
else:
|
||||
print(f"[WARNING] Puerto {host_port} ocupado, probando el siguiente...")
|
||||
host_port += 1 # Incrementa si el puerto está ocupado
|
||||
|
||||
if host_port > 65000:
|
||||
raise Exception("Se superó el límite de puertos disponibles.")
|
||||
|
||||
custom_ports_yaml = "\n".join(custom_ports)
|
||||
print(f"[INFO] Puertos personalizados configurados:\n{custom_ports_yaml}")
|
||||
else:
|
||||
custom_ports_yaml = "" # No agrega puertos si no se especifican
|
||||
print("[INFO] No se especificaron puertos internos.")
|
||||
|
||||
# Genera el contenido del archivo docker-compose dinámicamente
|
||||
docker_compose_content = f"""
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
{service_name}:
|
||||
image: {image_tag} # Usar la imagen base directamente
|
||||
container_name: {container_name}
|
||||
networks:
|
||||
- {network_name}
|
||||
restart: always
|
||||
tty: true
|
||||
volumes:
|
||||
- ./app:/app
|
||||
ports:
|
||||
{custom_ports_yaml}
|
||||
command: tail -f /dev/null # Mantener activo el contenedor
|
||||
|
||||
networks:
|
||||
{network_name}:
|
||||
driver: bridge
|
||||
"""
|
||||
|
||||
# Guarda el archivo docker-compose generado
|
||||
with open(new_docker_compose_file, 'w') as file:
|
||||
file.write(docker_compose_content)
|
||||
|
||||
# Muestra el contenido generado para depuración
|
||||
print(f"[DEBUG] Contenido del archivo {new_docker_compose_file}:\n")
|
||||
print(docker_compose_content)
|
||||
|
||||
# Ejecuta docker-compose con el archivo nuevo y captura la salida
|
||||
print("[INFO] Ejecutando docker compose...")
|
||||
result = subprocess.run(
|
||||
f'docker compose -f {new_docker_compose_file} up -d --no-build',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
# Muestra el resultado del comando
|
||||
if result.returncode != 0:
|
||||
print(f"[ERROR] Error al ejecutar docker compose:\n{result.stderr}")
|
||||
raise Exception("Error al ejecutar docker-compose")
|
||||
else:
|
||||
print(f"[INFO] Contenedor iniciado exitosamente:\n{result.stdout}")
|
||||
|
||||
# Mostrar contenedores activos y detenidos
|
||||
print("[DEBUG] Contenedores activos y detenidos:")
|
||||
subprocess.run("docker ps -a", shell=True)
|
||||
|
||||
# Obtener el ID del contenedor creado
|
||||
container_id = subprocess.getoutput(f"docker ps -qf name={container_name}")
|
||||
if not container_id:
|
||||
print(f"[ERROR] No se pudo obtener el ID del contenedor {container_name}.")
|
||||
raise Exception("No se pudo obtener el ID del contenedor")
|
||||
|
||||
print(f"[INFO] ID del contenedor: {container_id}")
|
||||
|
||||
# Mostrar logs del contenedor si está detenido
|
||||
print("[INFO] Mostrando logs del contenedor:")
|
||||
subprocess.run(f"docker logs {container_id}", shell=True)
|
||||
|
||||
# Guardar los datos del contenedor en el archivo JSON
|
||||
save_container_data({
|
||||
'id': container_id,
|
||||
'name': container_name,
|
||||
'network': network_name,
|
||||
'image': image_tag,
|
||||
'compose_file': new_docker_compose_file,
|
||||
'creation_timestamp': datetime.now().isoformat(),
|
||||
'ports': ports_mapping # Agrega la información de los puertos mapeados
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Error: {str(e)}")
|
||||
|
||||
finally:
|
||||
# Eliminar el archivo docker-compose generado si existe
|
||||
if os.path.exists(new_docker_compose_file):
|
||||
print(f"[INFO] Eliminando archivo temporal: {new_docker_compose_file}")
|
||||
os.remove(new_docker_compose_file)
|
||||
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Guardar datos del contenedor en JSON
|
||||
# -------------------------------
|
||||
def save_container_data(container_data):
|
||||
# Cargar datos existentes si el archivo existe y no está vacío
|
||||
if os.path.exists(CONTAINER_DATA_FILE) and os.path.getsize(CONTAINER_DATA_FILE) > 0:
|
||||
with open(CONTAINER_DATA_FILE, 'r') as file:
|
||||
try:
|
||||
data = json.load(file) # Cargar datos existentes
|
||||
except json.JSONDecodeError:
|
||||
data = [] # Si hay error al leer, inicializar como lista vacía
|
||||
else:
|
||||
# Crear el archivo vacío y usar una lista vacía
|
||||
with open(CONTAINER_DATA_FILE, 'w') as file:
|
||||
json.dump([], file)
|
||||
data = [] # Inicializar como lista vacía
|
||||
|
||||
# Agregar nuevo contenedor
|
||||
data.append(container_data)
|
||||
|
||||
# Guardar datos actualizados
|
||||
with open(CONTAINER_DATA_FILE, 'w') as file:
|
||||
json.dump(data, file, indent=4)
|
||||
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Limpiar imágenes huérfanas
|
||||
# -------------------------------
|
||||
def clean_unused_images():
|
||||
print("➤ Eliminando imágenes huérfanas...")
|
||||
os.system('docker image prune -f')
|
||||
|
||||
# -------------------------------
|
||||
# Función: Limpiar redes huérfanas
|
||||
# -------------------------------
|
||||
def clean_unused_networks():
|
||||
print("➤ Eliminando redes huérfanas...")
|
||||
os.system('docker network prune -f')
|
||||
|
||||
|
||||
######################################### -------------------------------
|
||||
# Ejecución del script
|
||||
######################################### -------------------------------
|
||||
if __name__ == "__main__":
|
||||
|
||||
|
||||
# Crear contenedores y guardarlos en el JSON
|
||||
for _ in range(NUM_CONTAINERS):
|
||||
run_docker_compose(internal_ports=PUERTOS_INTERNOS)
|
||||
print("➤ Contenedores creados y guardados en el JSON")
|
||||
|
||||
# Limpiar imágenes huérfanas
|
||||
clean_unused_images()
|
||||
# Limpiar redes huérfanas
|
||||
clean_unused_networks()
|
||||
Reference in New Issue
Block a user