Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed162d3c1d | ||
|
|
d07fab99a6 | ||
|
|
511978666a | ||
|
|
453deac601 |
@@ -8,8 +8,10 @@ This documents the *current* workflow and the *target* workflow once profiles +
|
|||||||
- Nginx + Pi‑Kit dashboard
|
- Nginx + Pi‑Kit dashboard
|
||||||
- DietPi dashboard
|
- DietPi dashboard
|
||||||
3) Update the system if needed.
|
3) Update the system if needed.
|
||||||
4) Run the prep scrub + verify:
|
4) Run the prep scrub + verify (prep now prompts to shut down):
|
||||||
- `sudo ./pikit-prep.sh`
|
- `sudo ./pikit-prep.sh`
|
||||||
|
- (optional) `sudo ./pikit-prep.sh --no-shutdown`
|
||||||
|
- (optional) `sudo ./pikit-prep.sh --shutdown-now`
|
||||||
- `./pikit-smoke-test.sh`
|
- `./pikit-smoke-test.sh`
|
||||||
- (optional) `sudo ./pikit-prep.sh --check-only`
|
- (optional) `sudo ./pikit-prep.sh --check-only`
|
||||||
5) Image the SD card with DietPi Imager.
|
5) Image the SD card with DietPi Imager.
|
||||||
@@ -25,8 +27,10 @@ This documents the *current* workflow and the *target* workflow once profiles +
|
|||||||
4) Add dashboard services using the UI (Add Service modal).
|
4) Add dashboard services using the UI (Add Service modal).
|
||||||
5) Open any needed ports in ufw (done as part of testing/config):
|
5) Open any needed ports in ufw (done as part of testing/config):
|
||||||
- `sudo ufw allow from <LAN subnet> to any port <port>`
|
- `sudo ufw allow from <LAN subnet> to any port <port>`
|
||||||
6) Run the prep scrub + verify:
|
6) Run the prep scrub + verify (prep now prompts to shut down):
|
||||||
- `sudo ./pikit-prep.sh`
|
- `sudo ./pikit-prep.sh`
|
||||||
|
- (optional) `sudo ./pikit-prep.sh --no-shutdown`
|
||||||
|
- (optional) `sudo ./pikit-prep.sh --shutdown-now`
|
||||||
- `./pikit-smoke-test.sh`
|
- `./pikit-smoke-test.sh`
|
||||||
- (optional) `sudo ./pikit-prep.sh --check-only`
|
- (optional) `sudo ./pikit-prep.sh --check-only`
|
||||||
7) Image the SD card via the QEMU DietPi VM:
|
7) Image the SD card via the QEMU DietPi VM:
|
||||||
@@ -54,8 +58,10 @@ This documents the *current* workflow and the *target* workflow once profiles +
|
|||||||
- Merges services into `/etc/pikit/services.json` (idempotent).
|
- Merges services into `/etc/pikit/services.json` (idempotent).
|
||||||
5) Run the drift check (planned script):
|
5) Run the drift check (planned script):
|
||||||
- Confirms services + ports match the profile + base.
|
- Confirms services + ports match the profile + base.
|
||||||
6) Run the prep scrub + verify:
|
6) Run the prep scrub + verify (prep now prompts to shut down):
|
||||||
- `sudo ./pikit-prep.sh`
|
- `sudo ./pikit-prep.sh`
|
||||||
|
- (optional) `sudo ./pikit-prep.sh --no-shutdown`
|
||||||
|
- (optional) `sudo ./pikit-prep.sh --shutdown-now`
|
||||||
- `./pikit-smoke-test.sh`
|
- `./pikit-smoke-test.sh`
|
||||||
- (optional) `sudo ./pikit-prep.sh --check-only`
|
- (optional) `sudo ./pikit-prep.sh --check-only`
|
||||||
7) Image the SD card with DietPi Imager.
|
7) Image the SD card with DietPi Imager.
|
||||||
@@ -84,8 +90,10 @@ Use the helper:
|
|||||||
- dashboard loads
|
- dashboard loads
|
||||||
- first‑boot completes
|
- first‑boot completes
|
||||||
4) Apply any required profile/services.
|
4) Apply any required profile/services.
|
||||||
5) Run prep + verify:
|
5) Run prep + verify (prep now prompts to shut down):
|
||||||
- `sudo ./pikit-prep.sh`
|
- `sudo ./pikit-prep.sh`
|
||||||
|
- (optional) `sudo ./pikit-prep.sh --no-shutdown`
|
||||||
|
- (optional) `sudo ./pikit-prep.sh --shutdown-now`
|
||||||
- `./pikit-smoke-test.sh`
|
- `./pikit-smoke-test.sh`
|
||||||
6) Power down cleanly.
|
6) Power down cleanly.
|
||||||
7) Image the SD card (DietPi Imager via QEMU or on‑device).
|
7) Image the SD card (DietPi Imager via QEMU or on‑device).
|
||||||
@@ -96,6 +104,48 @@ Use the helper:
|
|||||||
9) Smoke test the flashed image on a second SD card:
|
9) Smoke test the flashed image on a second SD card:
|
||||||
- boot → first‑boot → dashboard → services
|
- boot → first‑boot → dashboard → services
|
||||||
|
|
||||||
|
## 5) Release checklist (stable)
|
||||||
|
1) Ensure `main` is clean and all changes are pushed.
|
||||||
|
2) Update `pikit-web/data/version.json` to the new version.
|
||||||
|
3) Build the web assets:
|
||||||
|
- `npm --prefix pikit-web run build`
|
||||||
|
4) Run tests:
|
||||||
|
- `npm --prefix pikit-web test`
|
||||||
|
- `./pikit-smoke-test.sh`
|
||||||
|
5) Commit version bump and push.
|
||||||
|
6) Tag the release:
|
||||||
|
- `git tag vX.Y.Z && git push origin vX.Y.Z`
|
||||||
|
7) Build release bundle + manifest:
|
||||||
|
- `./tools/release/make-release.sh X.Y.Z https://git.44r0n.cc/44r0n7/pi-kit/releases/download/vX.Y.Z`
|
||||||
|
8) Generate changelog from git:
|
||||||
|
- `git log --pretty=format:'- %s (%h)' vPREV..HEAD > out/releases/CHANGELOG-X.Y.Z.txt`
|
||||||
|
9) Create the Gitea release and upload assets:
|
||||||
|
- `pikit-X.Y.Z.tar.gz`
|
||||||
|
- `manifest.json`
|
||||||
|
- `CHANGELOG-X.Y.Z.txt`
|
||||||
|
10) Update `manifests/manifest-stable.json` with new version + sha256 and push.
|
||||||
|
|
||||||
|
## 5) Release checklist (stable)
|
||||||
|
1) Ensure `main` is clean and all changes are pushed.
|
||||||
|
2) Update `pikit-web/data/version.json` to the new version.
|
||||||
|
3) Build the web assets:
|
||||||
|
- `npm --prefix pikit-web run build`
|
||||||
|
4) Run tests:
|
||||||
|
- `npm --prefix pikit-web test`
|
||||||
|
- `./pikit-smoke-test.sh`
|
||||||
|
5) Commit version bump and push.
|
||||||
|
6) Tag the release:
|
||||||
|
- `git tag vX.Y.Z && git push origin vX.Y.Z`
|
||||||
|
7) Build release bundle + manifest:
|
||||||
|
- `./tools/release/make-release.sh X.Y.Z https://git.44r0n.cc/44r0n7/pi-kit/releases/download/vX.Y.Z`
|
||||||
|
8) Generate changelog from git:
|
||||||
|
- `git log --pretty=format:'- %s (%h)' vPREV..HEAD > out/releases/CHANGELOG-X.Y.Z.txt`
|
||||||
|
9) Create the Gitea release and upload assets:
|
||||||
|
- `pikit-X.Y.Z.tar.gz`
|
||||||
|
- `manifest.json`
|
||||||
|
- `CHANGELOG-X.Y.Z.txt`
|
||||||
|
10) Update `manifests/manifest-stable.json` with new version + sha256 and push.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- Profiles are additive to the base image defaults; do not include Pi‑Kit or DietPi dashboard entries in profiles.
|
- Profiles are additive to the base image defaults; do not include Pi‑Kit or DietPi dashboard entries in profiles.
|
||||||
- Keep `RESCUE.md` in `/root` and `/home/dietpi` only (not in `/var/www`).
|
- Keep `RESCUE.md` in `/root` and `/home/dietpi` only (not in `/var/www`).
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"_release_date": "2025-12-10T00:00:00Z",
|
"_release_date": "2026-01-03T05:16:09Z",
|
||||||
"bundle": "https://git.44r0n.cc/44r0n7/pi-kit/releases/download/v0.1.2/pikit-0.1.2.tar.gz",
|
"bundle": "https://git.44r0n.cc/44r0n7/pi-kit/releases/download/v0.1.3/pikit-0.1.3.tar.gz",
|
||||||
"changelog": "https://git.44r0n.cc/44r0n7/pi-kit/releases/download/v0.1.2/CHANGELOG-0.1.2.txt",
|
"changelog": "https://git.44r0n.cc/44r0n7/pi-kit/releases/download/v0.1.3/CHANGELOG-0.1.3.txt",
|
||||||
"files": [
|
"files": [
|
||||||
{ "path": "bundle.tar.gz", "sha256": "8d2e0f8b260063cab0d52e862cb42f10472a643123f984af0248592479dd613d" }
|
{ "path": "bundle.tar.gz", "sha256": "a31db945f08a8cdb0906a913b3b5507cc50225e9ce6b23bef525951d23335865" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,12 @@ PIKIT_SSH_OPTS="${PIKIT_SSH_OPTS:-}"
|
|||||||
PIKIT_REMOTE_TMP="${PIKIT_REMOTE_TMP:-/tmp/pikit-prep.sh}"
|
PIKIT_REMOTE_TMP="${PIKIT_REMOTE_TMP:-/tmp/pikit-prep.sh}"
|
||||||
PIKIT_SELF_DELETE="${PIKIT_SELF_DELETE:-0}"
|
PIKIT_SELF_DELETE="${PIKIT_SELF_DELETE:-0}"
|
||||||
PIKIT_FORCE_PASSWORD_CHANGE="${PIKIT_FORCE_PASSWORD_CHANGE:-1}"
|
PIKIT_FORCE_PASSWORD_CHANGE="${PIKIT_FORCE_PASSWORD_CHANGE:-1}"
|
||||||
|
PIKIT_SHUTDOWN_AFTER_PREP="${PIKIT_SHUTDOWN_AFTER_PREP:-1}"
|
||||||
|
PIKIT_SHUTDOWN_PROMPT="${PIKIT_SHUTDOWN_PROMPT:-1}"
|
||||||
|
|
||||||
MODE="both"
|
MODE="both"
|
||||||
LOCAL_ONLY=0
|
LOCAL_ONLY=0
|
||||||
|
DID_PREP=0
|
||||||
|
|
||||||
ERRORS=0
|
ERRORS=0
|
||||||
WARNINGS=0
|
WARNINGS=0
|
||||||
@@ -32,10 +35,14 @@ Options:
|
|||||||
--prep-only Run prep only (no check)
|
--prep-only Run prep only (no check)
|
||||||
--check-only Run checks only (no prep)
|
--check-only Run checks only (no prep)
|
||||||
--local Force local execution (no SSH copy)
|
--local Force local execution (no SSH copy)
|
||||||
|
--shutdown-now Shutdown after prep completes without prompting
|
||||||
|
--no-shutdown Skip shutdown prompt after prep
|
||||||
--help Show this help
|
--help Show this help
|
||||||
|
|
||||||
Env:
|
Env:
|
||||||
PIKIT_FORCE_PASSWORD_CHANGE=0 Skip forcing a password change (default is on)
|
PIKIT_FORCE_PASSWORD_CHANGE=0 Skip forcing a password change (default is on)
|
||||||
|
PIKIT_SHUTDOWN_AFTER_PREP=0 Skip shutdown prompt after prep (default on)
|
||||||
|
PIKIT_SHUTDOWN_PROMPT=0 Skip shutdown prompt (default on)
|
||||||
USAGE
|
USAGE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +77,8 @@ parse_args() {
|
|||||||
--prep-only) MODE="prep" ;;
|
--prep-only) MODE="prep" ;;
|
||||||
--check-only) MODE="check" ;;
|
--check-only) MODE="check" ;;
|
||||||
--local) LOCAL_ONLY=1 ;;
|
--local) LOCAL_ONLY=1 ;;
|
||||||
|
--shutdown-now) PIKIT_SHUTDOWN_AFTER_PREP=1; PIKIT_SHUTDOWN_PROMPT=0 ;;
|
||||||
|
--no-shutdown) PIKIT_SHUTDOWN_AFTER_PREP=0 ;;
|
||||||
--help|-h) usage; exit 0 ;;
|
--help|-h) usage; exit 0 ;;
|
||||||
*)
|
*)
|
||||||
echo "[FAIL] Unknown argument: $arg" >&2
|
echo "[FAIL] Unknown argument: $arg" >&2
|
||||||
@@ -86,12 +95,16 @@ run_remote() {
|
|||||||
[ "$arg" = "--local" ] && continue
|
[ "$arg" = "--local" ] && continue
|
||||||
forward+=("$arg")
|
forward+=("$arg")
|
||||||
done
|
done
|
||||||
|
local ssh_tty=()
|
||||||
|
if [ "$PIKIT_SHUTDOWN_AFTER_PREP" -eq 1 ] && [ "$PIKIT_SHUTDOWN_PROMPT" -eq 1 ] && [ -t 0 ]; then
|
||||||
|
ssh_tty=(-t)
|
||||||
|
fi
|
||||||
if ! command -v scp >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then
|
if ! command -v scp >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then
|
||||||
echo "[FAIL] ssh/scp not available for remote prep" >&2
|
echo "[FAIL] ssh/scp not available for remote prep" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
scp -i "$PIKIT_SSH_KEY" $PIKIT_SSH_OPTS "$SCRIPT_PATH" "${PIKIT_USER}@${PIKIT_HOST}:${PIKIT_REMOTE_TMP}"
|
scp -i "$PIKIT_SSH_KEY" $PIKIT_SSH_OPTS "$SCRIPT_PATH" "${PIKIT_USER}@${PIKIT_HOST}:${PIKIT_REMOTE_TMP}"
|
||||||
ssh -i "$PIKIT_SSH_KEY" $PIKIT_SSH_OPTS "${PIKIT_USER}@${PIKIT_HOST}" \
|
ssh "${ssh_tty[@]}" -i "$PIKIT_SSH_KEY" $PIKIT_SSH_OPTS "${PIKIT_USER}@${PIKIT_HOST}" \
|
||||||
"sudo PIKIT_SELF_DELETE=1 bash ${PIKIT_REMOTE_TMP} --local ${forward[*]}; rc=\$?; rm -f ${PIKIT_REMOTE_TMP}; exit \$rc"
|
"sudo PIKIT_SELF_DELETE=1 bash ${PIKIT_REMOTE_TMP} --local ${forward[*]}; rc=\$?; rm -f ${PIKIT_REMOTE_TMP}; exit \$rc"
|
||||||
exit $?
|
exit $?
|
||||||
}
|
}
|
||||||
@@ -607,6 +620,33 @@ finalize() {
|
|||||||
echo "[OK] Prep/check completed."
|
echo "[OK] Prep/check completed."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybe_shutdown() {
|
||||||
|
if [ "$PIKIT_SHUTDOWN_AFTER_PREP" -ne 1 ] || [ "$DID_PREP" -ne 1 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local do_shutdown=1
|
||||||
|
if [ "$PIKIT_SHUTDOWN_PROMPT" -eq 1 ]; then
|
||||||
|
if [ -t 0 ]; then
|
||||||
|
local reply=""
|
||||||
|
printf '\nShutdown now? [y/N] '
|
||||||
|
read -r reply || reply=""
|
||||||
|
case "${reply,,}" in
|
||||||
|
y|yes) do_shutdown=1 ;;
|
||||||
|
*) do_shutdown=0 ;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
status WARN "no TTY; skipping shutdown (use --shutdown-now to force)"
|
||||||
|
do_shutdown=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$do_shutdown" -eq 1 ]; then
|
||||||
|
status OK "Shutting down"
|
||||||
|
shutdown -f now || status FAIL "shutdown"
|
||||||
|
else
|
||||||
|
status OK "Shutdown skipped"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
maybe_self_delete() {
|
maybe_self_delete() {
|
||||||
if [ "$PIKIT_SELF_DELETE" -eq 1 ] && [[ "$SCRIPT_PATH" == /tmp/* ]]; then
|
if [ "$PIKIT_SELF_DELETE" -eq 1 ] && [[ "$SCRIPT_PATH" == /tmp/* ]]; then
|
||||||
rm -f "$SCRIPT_PATH" || true
|
rm -f "$SCRIPT_PATH" || true
|
||||||
@@ -623,15 +663,17 @@ main() {
|
|||||||
require_root
|
require_root
|
||||||
|
|
||||||
case "$MODE" in
|
case "$MODE" in
|
||||||
prep) prep_image ;;
|
prep) prep_image; DID_PREP=1 ;;
|
||||||
check) check_image ;;
|
check) check_image ;;
|
||||||
both)
|
both)
|
||||||
prep_image
|
prep_image
|
||||||
|
DID_PREP=1
|
||||||
check_image
|
check_image
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
finalize
|
finalize
|
||||||
|
maybe_shutdown
|
||||||
maybe_self_delete
|
maybe_self_delete
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.3"
|
"version": "0.1.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default defineConfig({
|
|||||||
trace: 'retain-on-failure',
|
trace: 'retain-on-failure',
|
||||||
},
|
},
|
||||||
webServer: {
|
webServer: {
|
||||||
command: 'npm run dev',
|
command: 'node tests/mock-api.js & npm run dev',
|
||||||
url: BASE_URL,
|
url: BASE_URL,
|
||||||
reuseExistingServer: !process.env.CI,
|
reuseExistingServer: !process.env.CI,
|
||||||
stdout: 'pipe',
|
stdout: 'pipe',
|
||||||
|
|||||||
85
pikit-web/tests/mock-api.js
Normal file
85
pikit-web/tests/mock-api.js
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import http from 'http';
|
||||||
|
|
||||||
|
const port = Number(process.env.PIKIT_MOCK_API_PORT || 4000);
|
||||||
|
|
||||||
|
const updatesConfig = {
|
||||||
|
enabled: false,
|
||||||
|
scope: 'security',
|
||||||
|
cleanup: false,
|
||||||
|
bandwidth_limit_kbps: null,
|
||||||
|
auto_reboot: false,
|
||||||
|
reboot_time: '04:30',
|
||||||
|
reboot_with_users: false,
|
||||||
|
update_time: '04:00',
|
||||||
|
upgrade_time: '04:30',
|
||||||
|
state: { enabled: false },
|
||||||
|
};
|
||||||
|
|
||||||
|
const routes = {
|
||||||
|
'/health': { ok: true },
|
||||||
|
'/api/status': {
|
||||||
|
hostname: 'pikit-test',
|
||||||
|
uptime_seconds: 0,
|
||||||
|
load: [0, 0, 0],
|
||||||
|
memory_mb: { total: 1024, free: 1024 },
|
||||||
|
disk_mb: { total: 1024, free: 1024 },
|
||||||
|
cpu_temp_c: 35.0,
|
||||||
|
lan_ip: '127.0.0.1',
|
||||||
|
os_version: 'DietPi',
|
||||||
|
auto_updates_enabled: false,
|
||||||
|
auto_updates: { enabled: false },
|
||||||
|
updates_config: updatesConfig,
|
||||||
|
reboot_required: false,
|
||||||
|
ready: true,
|
||||||
|
services: [],
|
||||||
|
},
|
||||||
|
'/api/firstboot': {
|
||||||
|
state: 'done',
|
||||||
|
steps: [],
|
||||||
|
current_step: null,
|
||||||
|
log_tail: '',
|
||||||
|
error_present: false,
|
||||||
|
error_path: '/api/firstboot/error',
|
||||||
|
ca_hash: null,
|
||||||
|
ca_url: '/assets/pikit-ca.crt',
|
||||||
|
},
|
||||||
|
'/api/firstboot/error': { present: false, text: '' },
|
||||||
|
'/api/services': { services: [] },
|
||||||
|
'/api/updates/config': updatesConfig,
|
||||||
|
'/api/updates/auto': { enabled: false, details: { enabled: false } },
|
||||||
|
'/api/update/status': {
|
||||||
|
status: 'up_to_date',
|
||||||
|
current_version: '0.0.0',
|
||||||
|
latest_version: '0.0.0',
|
||||||
|
message: 'Mocked',
|
||||||
|
channel: 'stable',
|
||||||
|
in_progress: false,
|
||||||
|
},
|
||||||
|
'/api/update/releases': { releases: [] },
|
||||||
|
'/api/diag/log': { entries: [], state: { enabled: false, level: 'normal' } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
const url = (req.url || '/').split('?')[0];
|
||||||
|
const body = routes[url] || (url.startsWith('/api/') ? {} : null);
|
||||||
|
|
||||||
|
if (body === null) {
|
||||||
|
res.writeHead(404, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({ error: 'not found' }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify(body));
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(port, '127.0.0.1', () => {
|
||||||
|
console.log(`[mock-api] listening on 127.0.0.1:${port}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const shutdown = () => {
|
||||||
|
server.close(() => process.exit(0));
|
||||||
|
};
|
||||||
|
|
||||||
|
process.on('SIGTERM', shutdown);
|
||||||
|
process.on('SIGINT', shutdown);
|
||||||
@@ -3,17 +3,24 @@
|
|||||||
# Prints a one-time SSH hardening tip after the forced password change.
|
# Prints a one-time SSH hardening tip after the forced password change.
|
||||||
|
|
||||||
FLAG="/var/lib/pikit/first-login.notice"
|
FLAG="/var/lib/pikit/first-login.notice"
|
||||||
|
DONE_FILE=".pikit-first-login.done"
|
||||||
|
|
||||||
case "$-" in
|
case "$-" in
|
||||||
*i*) interactive=1 ;;
|
*i*) interactive=1 ;;
|
||||||
*) interactive=0 ;;
|
*) interactive=0 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [ "$interactive" -eq 1 ] && [ -f "$FLAG" ]; then
|
USER_NAME="$(id -un 2>/dev/null || echo "")"
|
||||||
echo ""
|
DONE_PATH="${HOME:-}/$DONE_FILE"
|
||||||
echo "Pi-Kit: For better security, set up an SSH key and disable password auth once working."
|
|
||||||
echo " Example: ssh-keygen -t ed25519"
|
if [ "$interactive" -eq 1 ] && [ -f "$FLAG" ] && [ "$USER_NAME" = "dietpi" ]; then
|
||||||
echo " ssh-copy-id dietpi@pikit.local"
|
if [ -n "${HOME:-}" ] && [ -d "${HOME:-}" ] && [ ! -f "$DONE_PATH" ]; then
|
||||||
echo ""
|
echo ""
|
||||||
rm -f "$FLAG" 2>/dev/null || true
|
echo "Pi-Kit: For better security, set up an SSH key and disable password auth once working."
|
||||||
|
echo " Run these from your computer (not the Pi):"
|
||||||
|
echo " ssh-keygen -t ed25519"
|
||||||
|
echo " ssh-copy-id dietpi@pikit.local"
|
||||||
|
echo ""
|
||||||
|
:> "$DONE_PATH" 2>/dev/null || true
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user