underpost 2.99.5 → 2.99.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/baremetal/commission-workflows.json +43 -6
- package/bin/deploy.js +3 -0
- package/cli.md +39 -15
- package/examples/static-page/README.md +80 -13
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +40 -0
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +40 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +2 -3
- package/scripts/maas-setup.sh +13 -9
- package/scripts/rocky-kickstart.sh +294 -0
- package/src/cli/baremetal.js +229 -233
- package/src/cli/cloud-init.js +25 -43
- package/src/cli/index.js +40 -5
- package/src/cli/kickstart.js +149 -0
- package/src/cli/run.js +43 -10
- package/src/cli/static.js +27 -1
- package/src/client/components/core/Docs.js +22 -3
- package/src/index.js +12 -1
- package/src/server/backup.js +11 -4
- package/src/server/client-build-docs.js +1 -1
- package/src/server/conf.js +0 -22
- package/src/server/cron.js +339 -130
- package/src/server/dns.js +10 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Rocky Linux 9 - Anaconda %pre Ephemeral Commissioning Script
|
|
3
|
+
# Variables ROOT_PASS, AUTHORIZED_KEYS, ADMIN_USER must be set before this script runs.
|
|
4
|
+
|
|
5
|
+
set +e
|
|
6
|
+
|
|
7
|
+
# 1. Set root password
|
|
8
|
+
if [ -n "$ROOT_PASS" ]; then
|
|
9
|
+
echo "root:$ROOT_PASS" | chpasswd 2>/dev/null || \
|
|
10
|
+
echo "$ROOT_PASS" | passwd --stdin root 2>/dev/null || {
|
|
11
|
+
HASH=$(python3 -c "import crypt; print(crypt.crypt('$ROOT_PASS', crypt.mksalt(crypt.METHOD_SHA512)))" 2>/dev/null || \
|
|
12
|
+
openssl passwd -6 "$ROOT_PASS" 2>/dev/null)
|
|
13
|
+
[ -n "$HASH" ] && sed -i "s|^root:[^:]*:|root:$HASH:|" /etc/shadow 2>/dev/null
|
|
14
|
+
}
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# 2. SSH authorized_keys for root
|
|
18
|
+
if [ -n "$AUTHORIZED_KEYS" ]; then
|
|
19
|
+
mkdir -p /root/.ssh && chmod 700 /root/.ssh
|
|
20
|
+
echo "$AUTHORIZED_KEYS" > /root/.ssh/authorized_keys
|
|
21
|
+
chmod 600 /root/.ssh/authorized_keys
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# 3. Create admin user
|
|
25
|
+
if command -v useradd >/dev/null 2>&1; then
|
|
26
|
+
useradd -m -G wheel "$ADMIN_USER" 2>/dev/null || true
|
|
27
|
+
else
|
|
28
|
+
NEXT_UID=$(awk -F: 'BEGIN{max=999} $3>max && $3<60000{max=$3} END{print max+1}' /etc/passwd 2>/dev/null || echo 1001)
|
|
29
|
+
if ! grep -q "^$ADMIN_USER:" /etc/passwd 2>/dev/null; then
|
|
30
|
+
echo "$ADMIN_USER:x:$NEXT_UID:$NEXT_UID:$ADMIN_USER:/home/$ADMIN_USER:/bin/bash" >> /etc/passwd
|
|
31
|
+
echo "$ADMIN_USER:x:$NEXT_UID:" >> /etc/group 2>/dev/null
|
|
32
|
+
echo "$ADMIN_USER:!:19000:0:99999:7:::" >> /etc/shadow 2>/dev/null
|
|
33
|
+
mkdir -p /home/$ADMIN_USER
|
|
34
|
+
fi
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
if [ -n "$ROOT_PASS" ]; then
|
|
38
|
+
echo "$ADMIN_USER:$ROOT_PASS" | chpasswd 2>/dev/null || \
|
|
39
|
+
echo "$ROOT_PASS" | passwd --stdin "$ADMIN_USER" 2>/dev/null || {
|
|
40
|
+
HASH=$(python3 -c "import crypt; print(crypt.crypt('$ROOT_PASS', crypt.mksalt(crypt.METHOD_SHA512)))" 2>/dev/null || \
|
|
41
|
+
openssl passwd -6 "$ROOT_PASS" 2>/dev/null)
|
|
42
|
+
[ -n "$HASH" ] && sed -i "s|^$ADMIN_USER:[^:]*:|$ADMIN_USER:$HASH:|" /etc/shadow 2>/dev/null
|
|
43
|
+
}
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [ -n "$AUTHORIZED_KEYS" ]; then
|
|
47
|
+
mkdir -p /home/$ADMIN_USER/.ssh && chmod 700 /home/$ADMIN_USER/.ssh
|
|
48
|
+
echo "$AUTHORIZED_KEYS" > /home/$ADMIN_USER/.ssh/authorized_keys
|
|
49
|
+
chmod 600 /home/$ADMIN_USER/.ssh/authorized_keys
|
|
50
|
+
chown -R $ADMIN_USER:$ADMIN_USER /home/$ADMIN_USER/.ssh 2>/dev/null || true
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
if [ -d /etc/sudoers.d ]; then
|
|
54
|
+
echo "$ADMIN_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$ADMIN_USER
|
|
55
|
+
chmod 0440 /etc/sudoers.d/$ADMIN_USER
|
|
56
|
+
elif [ -f /etc/sudoers ]; then
|
|
57
|
+
echo "$ADMIN_USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# 4. Configure sshd
|
|
61
|
+
if [ -f /etc/ssh/sshd_config ]; then
|
|
62
|
+
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
|
63
|
+
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
|
|
64
|
+
sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
|
65
|
+
sed -i 's/^#*ChallengeResponseAuthentication.*/ChallengeResponseAuthentication yes/' /etc/ssh/sshd_config
|
|
66
|
+
sed -i 's/^#*UsePAM.*/UsePAM yes/' /etc/ssh/sshd_config
|
|
67
|
+
sed -i 's/^#*KbdInteractiveAuthentication.*/KbdInteractiveAuthentication yes/' /etc/ssh/sshd_config
|
|
68
|
+
grep -q "^PasswordAuthentication" /etc/ssh/sshd_config || echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
|
|
69
|
+
grep -q "^PermitRootLogin" /etc/ssh/sshd_config || echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
|
|
70
|
+
grep -q "^PubkeyAuthentication" /etc/ssh/sshd_config || echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config
|
|
71
|
+
else
|
|
72
|
+
mkdir -p /etc/ssh
|
|
73
|
+
cat > /etc/ssh/sshd_config << 'SSHEOF'
|
|
74
|
+
Port 22
|
|
75
|
+
PermitRootLogin yes
|
|
76
|
+
PubkeyAuthentication yes
|
|
77
|
+
AuthorizedKeysFile .ssh/authorized_keys
|
|
78
|
+
PasswordAuthentication yes
|
|
79
|
+
ChallengeResponseAuthentication yes
|
|
80
|
+
KbdInteractiveAuthentication yes
|
|
81
|
+
UsePAM yes
|
|
82
|
+
Subsystem sftp /usr/libexec/openssh/sftp-server
|
|
83
|
+
SSHEOF
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if [ -d /etc/ssh/sshd_config.d ]; then
|
|
87
|
+
cat > /etc/ssh/sshd_config.d/00-underpost.conf << 'SSHCONF'
|
|
88
|
+
PermitRootLogin yes
|
|
89
|
+
PasswordAuthentication yes
|
|
90
|
+
PubkeyAuthentication yes
|
|
91
|
+
KbdInteractiveAuthentication yes
|
|
92
|
+
SSHCONF
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
|
|
96
|
+
ssh-keygen -A 2>/dev/null || {
|
|
97
|
+
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" 2>/dev/null
|
|
98
|
+
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" 2>/dev/null
|
|
99
|
+
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" 2>/dev/null
|
|
100
|
+
}
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# 5. Initialize rpmdb and dnf repos
|
|
104
|
+
mkdir -p /var/lib/rpm /var/cache/dnf /var/log/dnf /etc/yum.repos.d /etc/pki/rpm-gpg /etc/dnf/vars
|
|
105
|
+
echo "9" > /etc/dnf/vars/releasever
|
|
106
|
+
|
|
107
|
+
if ! grep -q "^VERSION_ID=" /etc/os-release 2>/dev/null; then
|
|
108
|
+
cat > /etc/os-release << 'OSREL'
|
|
109
|
+
NAME="Rocky Linux"
|
|
110
|
+
VERSION="9"
|
|
111
|
+
ID="rocky"
|
|
112
|
+
ID_LIKE="rhel centos fedora"
|
|
113
|
+
VERSION_ID="9"
|
|
114
|
+
PLATFORM_ID="platform:el9"
|
|
115
|
+
PRETTY_NAME="Rocky Linux 9 (Ephemeral Anaconda)"
|
|
116
|
+
ANSI_COLOR="0;32"
|
|
117
|
+
HOME_URL="https://rockylinux.org/"
|
|
118
|
+
OSREL
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
[ ! -f /etc/system-release ] && echo "Rocky Linux release 9 (Ephemeral)" > /etc/system-release
|
|
122
|
+
|
|
123
|
+
rpm --initdb 2>/dev/null || rpmdb --initdb 2>/dev/null || {
|
|
124
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
125
|
+
python3 -c "
|
|
126
|
+
import sqlite3, os
|
|
127
|
+
db_path = '/var/lib/rpm/rpmdb.sqlite'
|
|
128
|
+
if not os.path.exists(db_path):
|
|
129
|
+
conn = sqlite3.connect(db_path)
|
|
130
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Packages (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
131
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Name (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
132
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Basenames (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
133
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Installtid (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
134
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Providename (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
135
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Requirename (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
136
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Dirnames (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
137
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Sha1header (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
138
|
+
conn.execute('CREATE TABLE IF NOT EXISTS Sigmd5 (key BLOB NOT NULL, data BLOB NOT NULL)')
|
|
139
|
+
conn.commit()
|
|
140
|
+
conn.close()
|
|
141
|
+
" 2>/dev/null
|
|
142
|
+
fi
|
|
143
|
+
}
|
|
144
|
+
chmod -R 755 /var/lib/rpm 2>/dev/null
|
|
145
|
+
|
|
146
|
+
REPO_ARCH=$(uname -m)
|
|
147
|
+
|
|
148
|
+
rpm --import https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9 2>/dev/null || \
|
|
149
|
+
curl -fsSL https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9 -o /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 2>/dev/null || true
|
|
150
|
+
|
|
151
|
+
cat > /etc/dnf/dnf.conf << 'DNFCONF'
|
|
152
|
+
[main]
|
|
153
|
+
gpgcheck=1
|
|
154
|
+
installonly_limit=3
|
|
155
|
+
clean_requirements_on_remove=True
|
|
156
|
+
best=True
|
|
157
|
+
skip_if_unavailable=True
|
|
158
|
+
install_weak_deps=False
|
|
159
|
+
tsflags=nodocs
|
|
160
|
+
DNFCONF
|
|
161
|
+
|
|
162
|
+
cat > /etc/yum.repos.d/rocky-baseos.repo << REPOEOF
|
|
163
|
+
[baseos]
|
|
164
|
+
name=Rocky Linux 9 - BaseOS
|
|
165
|
+
baseurl=http://dl.rockylinux.org/pub/rocky/9/BaseOS/$REPO_ARCH/os/
|
|
166
|
+
gpgcheck=1
|
|
167
|
+
enabled=1
|
|
168
|
+
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
|
|
169
|
+
https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9
|
|
170
|
+
skip_if_unavailable=1
|
|
171
|
+
REPOEOF
|
|
172
|
+
|
|
173
|
+
cat > /etc/yum.repos.d/rocky-appstream.repo << REPOEOF2
|
|
174
|
+
[appstream]
|
|
175
|
+
name=Rocky Linux 9 - AppStream
|
|
176
|
+
baseurl=http://dl.rockylinux.org/pub/rocky/9/AppStream/$REPO_ARCH/os/
|
|
177
|
+
gpgcheck=1
|
|
178
|
+
enabled=1
|
|
179
|
+
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
|
|
180
|
+
https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9
|
|
181
|
+
skip_if_unavailable=1
|
|
182
|
+
REPOEOF2
|
|
183
|
+
|
|
184
|
+
cat > /etc/yum.repos.d/rocky-extras.repo << REPOEOF3
|
|
185
|
+
[extras]
|
|
186
|
+
name=Rocky Linux 9 - Extras
|
|
187
|
+
baseurl=http://dl.rockylinux.org/pub/rocky/9/extras/$REPO_ARCH/os/
|
|
188
|
+
gpgcheck=1
|
|
189
|
+
enabled=1
|
|
190
|
+
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
|
|
191
|
+
https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9
|
|
192
|
+
skip_if_unavailable=1
|
|
193
|
+
REPOEOF3
|
|
194
|
+
|
|
195
|
+
cat > /etc/yum.repos.d/rocky-crb.repo << REPOEOF4
|
|
196
|
+
[crb]
|
|
197
|
+
name=Rocky Linux 9 - CRB
|
|
198
|
+
baseurl=http://dl.rockylinux.org/pub/rocky/9/CRB/$REPO_ARCH/os/
|
|
199
|
+
gpgcheck=1
|
|
200
|
+
enabled=0
|
|
201
|
+
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
|
|
202
|
+
https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9
|
|
203
|
+
skip_if_unavailable=1
|
|
204
|
+
REPOEOF4
|
|
205
|
+
|
|
206
|
+
cat > /etc/yum.repos.d/epel.repo << REPOEOF5
|
|
207
|
+
[epel]
|
|
208
|
+
name=Extra Packages for Enterprise Linux 9
|
|
209
|
+
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-9&arch=$REPO_ARCH
|
|
210
|
+
gpgcheck=1
|
|
211
|
+
enabled=1
|
|
212
|
+
gpgkey=https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9
|
|
213
|
+
skip_if_unavailable=1
|
|
214
|
+
REPOEOF5
|
|
215
|
+
|
|
216
|
+
rpm --import https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9 2>/dev/null || \
|
|
217
|
+
curl -fsSL https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9 -o /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9 2>/dev/null || true
|
|
218
|
+
|
|
219
|
+
dnf makecache --releasever=9 --quiet 2>/dev/null || dnf makecache --releasever=9 2>/dev/null || true
|
|
220
|
+
|
|
221
|
+
# Install sudo
|
|
222
|
+
if ! command -v sudo >/dev/null 2>&1; then
|
|
223
|
+
dnf install -y --releasever=9 --nogpgcheck sudo 2>/dev/null || \
|
|
224
|
+
dnf install -y --releasever=9 --nogpgcheck --disableplugin='*' sudo 2>/dev/null || true
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
if command -v sudo >/dev/null 2>&1; then
|
|
228
|
+
mkdir -p /etc/sudoers.d
|
|
229
|
+
echo "$ADMIN_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$ADMIN_USER
|
|
230
|
+
chmod 0440 /etc/sudoers.d/$ADMIN_USER
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
cat > /home/$ADMIN_USER/.bash_profile 2>/dev/null << PROFILEEOF
|
|
234
|
+
if ! command -v sudo >/dev/null 2>&1; then
|
|
235
|
+
echo ""
|
|
236
|
+
echo "NOTE: sudo is not available. Use 'su -' to switch to root."
|
|
237
|
+
echo ""
|
|
238
|
+
fi
|
|
239
|
+
PROFILEEOF
|
|
240
|
+
chown $ADMIN_USER:$ADMIN_USER /home/$ADMIN_USER/.bash_profile 2>/dev/null || true
|
|
241
|
+
|
|
242
|
+
# Restart sshd
|
|
243
|
+
if command -v systemctl >/dev/null 2>&1; then
|
|
244
|
+
systemctl restart sshd 2>/dev/null || systemctl restart sshd.service 2>/dev/null
|
|
245
|
+
fi
|
|
246
|
+
SSHD_PID=$(cat /var/run/sshd.pid 2>/dev/null || pidof sshd 2>/dev/null | awk '{print $1}')
|
|
247
|
+
[ -n "$SSHD_PID" ] && kill -HUP "$SSHD_PID" 2>/dev/null
|
|
248
|
+
if ! pidof sshd >/dev/null 2>&1; then
|
|
249
|
+
/usr/sbin/sshd 2>/dev/null || sshd 2>/dev/null
|
|
250
|
+
fi
|
|
251
|
+
|
|
252
|
+
# 6. Status report
|
|
253
|
+
DETECTED_IP=$(ip -4 addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d/ -f1 | head -1)
|
|
254
|
+
|
|
255
|
+
echo ""
|
|
256
|
+
echo "=============================================="
|
|
257
|
+
echo "Underpost: Ephemeral SSHD Setup Complete"
|
|
258
|
+
echo "=============================================="
|
|
259
|
+
echo "Root login: root / (password set: $([ -n "$ROOT_PASS" ] && echo 'yes' || echo 'no'))"
|
|
260
|
+
echo "Admin user: $ADMIN_USER / (password set: $([ -n "$ROOT_PASS" ] && echo 'yes' || echo 'no'))"
|
|
261
|
+
echo "SSH keys: $([ -n "$AUTHORIZED_KEYS" ] && echo 'configured' || echo 'NOT configured')"
|
|
262
|
+
echo "sshd status: $(pidof sshd >/dev/null 2>&1 && echo "running (pid $(pidof sshd))" || echo 'NOT running')"
|
|
263
|
+
echo "sudo: $(command -v sudo >/dev/null 2>&1 && echo 'installed' || echo 'NOT available (use su -)')"
|
|
264
|
+
echo "IP address: $DETECTED_IP"
|
|
265
|
+
echo "=============================================="
|
|
266
|
+
|
|
267
|
+
# Physical console display (printf with \r\n for proper line breaks on serial/physical consoles)
|
|
268
|
+
{
|
|
269
|
+
printf "\r\n"
|
|
270
|
+
printf "██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗\r\n"
|
|
271
|
+
printf "██║░░░██║████╗░██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝\r\n"
|
|
272
|
+
printf "██║░░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██████╔╝██║░░██║╚█████╗░░░░██║░░░\r\n"
|
|
273
|
+
printf "██║░░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██╔═══╝░██║░░██║░╚═══██╗░░░██║░░░\r\n"
|
|
274
|
+
printf "╚██████╔╝██║░╚███║██████╔╝███████╗██║░░██║██║░░░░░╚█████╔╝██████╔╝░░░██║░░░\r\n"
|
|
275
|
+
printf "░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░\r\n"
|
|
276
|
+
printf "==============================================\r\n"
|
|
277
|
+
printf " Underpost Ephemeral Commissioning Active\r\n"
|
|
278
|
+
printf "==============================================\r\n"
|
|
279
|
+
printf " SSH as: root@%s\r\n" "$DETECTED_IP"
|
|
280
|
+
printf " or: %s@%s\r\n" "$ADMIN_USER" "$DETECTED_IP"
|
|
281
|
+
printf " Key: %s\r\n" "$([ -n "$AUTHORIZED_KEYS" ] && echo 'pubkey auth enabled' || echo 'password only')"
|
|
282
|
+
printf " dnf: ready (BaseOS, AppStream, Extras, EPEL)\r\n"
|
|
283
|
+
printf "==============================================\r\n"
|
|
284
|
+
printf "\r\n"
|
|
285
|
+
} > /dev/console 2>/dev/null || true
|
|
286
|
+
|
|
287
|
+
# 7. Infinite wait loop - keep Anaconda live environment active
|
|
288
|
+
while true; do
|
|
289
|
+
sleep 60
|
|
290
|
+
if ! pidof sshd >/dev/null 2>&1; then
|
|
291
|
+
echo "$(date): sshd not running, restarting..." >> /tmp/ks-pre.log
|
|
292
|
+
/usr/sbin/sshd 2>/dev/null || sshd 2>/dev/null
|
|
293
|
+
fi
|
|
294
|
+
done
|