From 66aefd616153d83894733632698dce37e3151eee Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 7 Aug 2026 13:20:18 +0800 Subject: [PATCH] fix(generators): call PKG_INSTALL without '$' under 'set -u' In bash with 'set -u', an undefined variable triggers an unbound-variable error. Functions don't satisfy '$FUNCNAME' expansion under set -u, so the previous fix that kept '$PKG_INSTALL pkg...' as the call syntax broke every call site: docker.sh: line 53: PKG_INSTALL: unbound variable Fix: drop the leading '$' in all 47 call sites across 6 generator files. 'PKG_INSTALL pkg...' is a normal command/function lookup and behaves identically under set -u or not. Verified: web UI served docker.sh now has 'PKG_INSTALL' (no $); 'bash -n' passes; smoke run with stubbed PATH hits real line-53 call site, mock apt-get receives correct args, exit 0, no unbound variable. Sampled 6 other generators also syntax-OK with $PKG_INSTALL count 0. --- generators/databases.py | 8 +++---- generators/middleware.py | 20 ++++++++--------- generators/monitoring.py | 6 +++--- generators/network.py | 6 +++--- generators/runtimes.py | 46 ++++++++++++++++++++-------------------- generators/system.py | 8 +++---- 6 files changed, 47 insertions(+), 47 deletions(-) diff --git a/generators/databases.py b/generators/databases.py index 1e6b492..e209e2b 100644 --- a/generators/databases.py +++ b/generators/databases.py @@ -27,7 +27,7 @@ class Memcached(Generator): listen = p.get("listen", "0.0.0.0") out = [bash_header(self.title)] out.append('log "Installing memcached..."') - out.append('$PKG_INSTALL memcached') + out.append('PKG_INSTALL memcached') out.append('cp /etc/memcached.conf /etc/memcached.conf.bak.$(date +%s) || true') out.append('sed -i "s/^-m .*/-m ' + mem + '/" /etc/memcached.conf') out.append('sed -i "s/^-p .*/-p ' + port + '/" /etc/memcached.conf') @@ -54,9 +54,9 @@ class SqliteTools(Generator): pyb = bool_str(p.get("install_python_bindings", True)) out = [bash_header(self.title)] out.append('log "Installing sqlite3..."') - out.append('$PKG_INSTALL sqlite3 libsqlite3-dev || $PKG_INSTALL sqlite sqlite-devel') + out.append('PKG_INSTALL sqlite3 libsqlite3-dev || PKG_INSTALL sqlite sqlite-devel') if pyb: - out.append('command -v pip3 >/dev/null || $PKG_INSTALL python3-pip') + out.append('command -v pip3 >/dev/null || PKG_INSTALL python3-pip') out.append('pip3 install --break-system-packages sqlite-utils || pip3 install sqlite-utils') out.append('sqlite3 --version') return "\n".join(out) + "\n" @@ -143,7 +143,7 @@ class ClickHouse(Generator): dp = p.get("data_path", "/var/lib/clickhouse") out = [bash_header(self.title)] out.append('log "Installing ClickHouse..."') - out.append('$PKG_INSTALL apt-transport-https ca-certificates curl || $PKG_INSTALL ca-certificates curl') + out.append('PKG_INSTALL apt-transport-https ca-certificates curl || PKG_INSTALL ca-certificates curl') out.append('mkdir -p /etc/apt/keyrings') out.append('curl -fsSL https://clickhouse.com/keys/clickhouse.asc | gpg --dearmor -o /etc/apt/keyrings/clickhouse.gpg') out.append('echo "deb [signed-by=/etc/apt/keyrings/clickhouse.gpg] https://packages.clickhouse.com/deb stable main" > /etc/apt/sources.list.d/clickhouse.list') diff --git a/generators/middleware.py b/generators/middleware.py index 78d761d..31bfdb8 100644 --- a/generators/middleware.py +++ b/generators/middleware.py @@ -414,7 +414,7 @@ class Nginx(Generator): out = [bash_header(self.title)] out.append('log "Installing nginx..."') - out.append('$PKG_INSTALL nginx openssl curl') + out.append('PKG_INSTALL nginx openssl curl') out.append('mkdir -p /etc/nginx/conf.d /var/www/html /etc/nginx/ssl') out.append('') # main nginx.conf (only override the worker_processes line if not 'auto') @@ -540,7 +540,7 @@ class HAProxy(Generator): out = [bash_header(self.title)] out.append('log "Installing haproxy..."') - out.append('$PKG_INSTALL haproxy') + out.append('PKG_INSTALL haproxy') out.append('cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak.$(date +%s) || true') out.append('mkdir -p /etc/haproxy') out.append('') @@ -623,7 +623,7 @@ class Keepalived(Generator): out = [bash_header(self.title)] out.append('log "Installing keepalived..."') - out.append('$PKG_INSTALL keepalived') + out.append('PKG_INSTALL keepalived') out.append('') out.append('cat > /etc/keepalived/keepalived.conf < /etc/redis/redis.conf </dev/null || $PKG_INSTALL java-11-openjdk-devel java-11-openjdk || $PKG_INSTALL default-jdk') + out.append('command -v java >/dev/null || PKG_INSTALL java-11-openjdk-devel java-11-openjdk || PKG_INSTALL default-jdk') out.append('useradd -r -s /bin/false ' + user + ' 2>/dev/null || true') out.append('cd /opt') out.append('curl -fsSL -o tomcat.tar.gz "' + url + '"') @@ -896,18 +896,18 @@ class Docker(Generator): out.append('log "Installing Docker..."') out.append('case "$PKG" in\n' ' apt-get)\n' - ' $PKG_INSTALL ca-certificates curl gnupg lsb-release\n' + ' PKG_INSTALL ca-certificates curl gnupg lsb-release\n' ' install -m 0755 -d /etc/apt/keyrings\n' ' curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg\n' ' chmod a+r /etc/apt/keyrings/docker.gpg\n' ' echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list\n' ' apt-get update\n' - ' $PKG_INSTALL docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n' + ' PKG_INSTALL docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n' ' ;;\n' ' yum|dnf)\n' - ' $PKG_INSTALL yum-utils\n' + ' PKG_INSTALL yum-utils\n' ' yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo || dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo\n' - ' $PKG_INSTALL docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n' + ' PKG_INSTALL docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n' ' ;;\n' 'esac') out.append('systemctl enable --now docker') @@ -1031,7 +1031,7 @@ class Zookeeper(Generator): out = [bash_header(self.title)] out.append('log "Installing Java + ZooKeeper..."') - out.append('command -v java >/dev/null || $PKG_INSTALL java-11-openjdk-devel java-11-openjdk || $PKG_INSTALL default-jdk') + out.append('command -v java >/dev/null || PKG_INSTALL java-11-openjdk-devel java-11-openjdk || PKG_INSTALL default-jdk') out.append('useradd -r -s /bin/false zookeeper 2>/dev/null || true') out.append('cd /opt') out.append('curl -fsSL -o zk.tar.gz https://archive.apache.org/dist/zookeeper/zookeeper-' + ver + '/apache-zookeeper-' + ver + '-bin.tar.gz') diff --git a/generators/monitoring.py b/generators/monitoring.py index ae8e3af..32864b3 100644 --- a/generators/monitoring.py +++ b/generators/monitoring.py @@ -150,17 +150,17 @@ class Grafana(Generator): out.append('log "Installing Grafana..."') out.append('case "$PKG" in\n' ' apt-get)\n' - ' $PKG_INSTALL -y software-properties-common\n' + ' PKG_INSTALL -y software-properties-common\n' ' mkdir -p /etc/apt/keyrings\n' ' wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | tee /etc/apt/keyrings/grafana.gpg > /dev/null\n' ' echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list\n' ' apt-get update\n' - ' $PKG_INSTALL grafana\n' + ' PKG_INSTALL grafana\n' ' ;;\n' ' yum|dnf)\n' ' cat > /etc/yum.repos.d/grafana.repo </dev/null || $PKG_INSTALL gcc make build-essential \\\n' + out.append('command -v gcc >/dev/null || PKG_INSTALL gcc make build-essential \\\n' ' libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \\\n' ' libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev \\\n' - ' || $PKG_INSTALL gcc make openssl-devel bzip2-devel libffi-devel zlib-devel \\\n' + ' || PKG_INSTALL gcc make openssl-devel bzip2-devel libffi-devel zlib-devel \\\n' ' readline-devel sqlite-devel ncurses-devel xz-devel') out.append('cd /tmp') out.append('curl -fsSL -o Python.tgz https://www.python.org/ftp/python/' + ver + '/Python-' + ver + '.tgz') @@ -192,7 +192,7 @@ class GCC(Generator): out = [bash_header(self.title)] out.append('log "Installing GCC ' + ver + ' from source..."') - out.append('$PKG_INSTALL wget gcc gcc-c++ make texinfo bison flex') + out.append('PKG_INSTALL wget gcc gcc-c++ make texinfo bison flex') out.append('cd /tmp') out.append('curl -fsSL -O https://ftp.gnu.org/gnu/gcc/gcc-' + ver + '/gcc-' + ver + '.tar.xz') out.append('tar -xJf gcc-' + ver + '.tar.xz') @@ -230,7 +230,7 @@ class Make(Generator): d = p.get("install_dir", "/opt/make") out = [bash_header(self.title)] out.append('log "Installing make ' + ver + '..."') - out.append('$PKG_INSTALL gcc make') + out.append('PKG_INSTALL gcc make') out.append('cd /tmp') out.append('curl -fsSL -O https://ftp.gnu.org/gnu/make/make-' + ver + '.tar.gz') out.append('tar -xzf make-' + ver + '.tar.gz') @@ -420,10 +420,10 @@ class PHP(Generator): exts = p.get("extensions", "mysqli,pdo,pdo_mysql,gd,mbstring,curl,xml,zip,intl,opcache,bcmath") out = [bash_header(self.title)] out.append('log "Installing PHP ' + ver + ' from source..."') - out.append('$PKG_INSTALL gcc make libxml2-dev libssl-dev libcurl4-openssl-dev \\\n' + out.append('PKG_INSTALL gcc make libxml2-dev libssl-dev libcurl4-openssl-dev \\\n' ' libonig-dev libzip-dev libicu-dev libsqlite3-dev libpng-dev libjpeg-dev \\\n' ' libfreetype6-dev libwebp-dev libxslt1-dev libreadline-dev 2>/dev/null \\\n' - ' || $PKG_INSTALL gcc make libxml2-devel openssl-devel libcurl-devel \\\n' + ' || PKG_INSTALL gcc make libxml2-devel openssl-devel libcurl-devel \\\n' ' libonig-devel libzip-devel libicu-devel sqlite-devel libpng-devel \\\n' ' libjpeg-devel freetype-devel libwebp-devel libxslt-devel readline-devel') out.append('cd /tmp') @@ -476,9 +476,9 @@ class Ruby(Generator): d = p.get("install_dir", "/opt/ruby") out = [bash_header(self.title)] out.append('log "Installing Ruby ' + ver + '..."') - out.append('$PKG_INSTALL gcc make build-essential libssl-dev libreadline-dev zlib1g-dev \\\n' + out.append('PKG_INSTALL gcc make build-essential libssl-dev libreadline-dev zlib1g-dev \\\n' ' libyaml-dev libgmp-dev libffi-dev libgdbm-dev libdb-dev libncurses5-dev 2>/dev/null \\\n' - ' || $PKG_INSTALL gcc make openssl-devel readline-devel zlib-devel \\\n' + ' || PKG_INSTALL gcc make openssl-devel readline-devel zlib-devel \\\n' ' libyaml-devel gmp-devel libffi-devel gdbm-devel ncurses-devel') out.append('cd /tmp') out.append('curl -fsSL -O https://cache.ruby-lang.org/pub/ruby/' + ver.split('.')[0] + '.' + ver.split('.')[1] + '/ruby-' + ver + '.tar.gz') @@ -520,8 +520,8 @@ class RustLang(Generator): out = [bash_header(self.title)] out.append('log "Installing rustup + ' + ch + '..."') - out.append('command -v gcc >/dev/null || $PKG_INSTALL gcc make build-essential \\\n' - ' || $PKG_INSTALL gcc make') + out.append('command -v gcc >/dev/null || PKG_INSTALL gcc make build-essential \\\n' + ' || PKG_INSTALL gcc make') if mirror: out.append('export RUSTUP_DIST_SERVER=https://rsproxy.cn') out.append('export RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup') @@ -567,15 +567,15 @@ class PostgreSQL(Generator): out.append('log "Installing PostgreSQL ' + ver + '..."') out.append('case "$PKG" in\n' ' apt-get)\n' - ' $PKG_INSTALL wget gnupg lsb-release ca-certificates\n' + ' PKG_INSTALL wget gnupg lsb-release ca-certificates\n' ' curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /usr/share/keyrings/pgdg.gpg\n' ' echo "deb [signed-by=/usr.share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list\n' ' apt-get update\n' - ' $PKG_INSTALL postgresql-' + ver + ' postgresql-client-' + ver + ' postgresql-contrib-' + ver + '\n' + ' PKG_INSTALL postgresql-' + ver + ' postgresql-client-' + ver + ' postgresql-contrib-' + ver + '\n' ' ;;\n' ' yum|dnf)\n' - ' $PKG_INSTALL https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm\n' - ' $PKG_INSTALL postgresql' + ver + '-server postgresql' + ver + '-contrib\n' + ' PKG_INSTALL https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm\n' + ' PKG_INSTALL postgresql' + ver + '-server postgresql' + ver + '-contrib\n' ' /usr/pgsql-' + ver + '/bin/postgresql-' + ver + '-setup initdb\n' ' ;;\n' 'esac') @@ -621,22 +621,22 @@ class MySQL(Generator): out.append('log "Installing MySQL ' + ver + '..."') out.append('case "$PKG" in\n' ' apt-get)\n' - ' $PKG_INSTALL wget gnupg lsb-release\n' + ' PKG_INSTALL wget gnupg lsb-release\n' ' wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb\n' ' DEBIAN_FRONTEND=noninteractive dpkg -i mysql-apt-config_0.8.29-1_all.deb || true\n' ' apt-get update\n' - ' $PKG_INSTALL mysql-server mysql-client\n' + ' PKG_INSTALL mysql-server mysql-client\n' ' ;;\n' ' yum|dnf)\n' - ' $PKG_INSTALL https://dev.mysql.com/get/mysql80-community-release-el$(rpm -E %{rhel})-1.noarch.rpm\n' - ' $PKG_INSTALL mysql-community-server mysql-community-client\n' + ' PKG_INSTALL https://dev.mysql.com/get/mysql80-community-release-el$(rpm -E %{rhel})-1.noarch.rpm\n' + ' PKG_INSTALL mysql-community-server mysql-community-client\n' ' ;;\n' 'esac') else: out.append('log "Installing MariaDB ' + ver + '..."') out.append('case "$PKG" in\n' - ' apt-get) $PKG_INSTALL mariadb-server mariadb-client ;;\n' - ' yum|dnf) $PKG_INSTALL mariadb-server mariadb ;;\n' + ' apt-get) PKG_INSTALL mariadb-server mariadb-client ;;\n' + ' yum|dnf) PKG_INSTALL mariadb-server mariadb ;;\n' 'esac') out.append('systemctl enable --now mysql || systemctl enable --now mariadb') out.append('sleep 3') @@ -682,11 +682,11 @@ class MongoDB(Generator): out.append('log "Installing MongoDB ' + ver + '..."') out.append('case "$PKG" in\n' ' apt-get)\n' - ' $PKG_INSTALL wget gnupg curl\n' + ' PKG_INSTALL wget gnupg curl\n' ' curl -fsSL https://www.mongodb.org/static/pgp/server-' + ver + '.asc | gpg --dearmor -o /usr/share/keyrings/mongodb.gpg\n' ' echo "deb [signed-by=/usr/share/keyrings/mongodb.gpg] https://repo.mongodb.org/apt/ubuntu $(grep VERSION_CODENAME /etc/os-release | cut -d= -f2)/mongodb-org/' + ver + ' multiverse" > /etc/apt/sources.list.d/mongodb-org-' + ver + '.list\n' ' apt-get update\n' - ' $PKG_INSTALL mongodb-org\n' + ' PKG_INSTALL mongodb-org\n' ' ;;\n' ' yum|dnf)\n' ' cat > /etc/yum.repos.d/mongodb-org-' + ver + '.repo < /etc/chrony/chrony.conf <