mirror of
https://github.com/recklessop/zroc.git
synced 2026-07-02 21:13:15 -04:00
ova: fix swap, auto-launch setup wizard, add password change step
- Replace direct storage layout with explicit partitioning (no swap) - Setup wizard now auto-launches on TTY1 via getty override instead of a separate systemd service that competed with console output - Add step 1/7: prompt user to change default zroc password on first boot - Update Makefile for QEMU-based build (was referencing old ovftool flow) - Add backend package-lock.json for Docker build Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+44
-53
@@ -1,64 +1,55 @@
|
||||
# zroc-ova/Makefile
|
||||
# zroc-ova/Makefile — Build and manage zROC appliance images
|
||||
VERSION ?= 1.0.0
|
||||
PACKER_DIR = packer
|
||||
OUTPUT_DIR = output
|
||||
OVA_NAME = zroc-appliance-$(VERSION)-ubuntu-26.04-amd64.ova
|
||||
VM_NAME = zroc-appliance
|
||||
ARTIFACT_PFX = $(VM_NAME)-$(VERSION)-ubuntu-24.04-amd64
|
||||
|
||||
.PHONY: all init validate build build-qemu package checksum clean help
|
||||
.PHONY: all build validate clean init docker-build docker-push help
|
||||
|
||||
all: build package checksum
|
||||
all: build ## Build everything (default)
|
||||
|
||||
init:
|
||||
cd $(PACKER_DIR) && packer init ubuntu-2604.pkr.hcl
|
||||
|
||||
validate: init
|
||||
cd $(PACKER_DIR) && packer validate \
|
||||
-var "vm_version=$(VERSION)" \
|
||||
-var-file=variables.pkrvars.hcl \
|
||||
ubuntu-2604.pkr.hcl
|
||||
@echo "✓ Template valid"
|
||||
|
||||
build: init
|
||||
@echo "==> Building zROC OVA v$(VERSION) with VMware builder"
|
||||
cd $(PACKER_DIR) && PACKER_LOG=1 packer build \
|
||||
-var "vm_version=$(VERSION)" \
|
||||
-var "headless=true" \
|
||||
-var-file=variables.pkrvars.hcl \
|
||||
ubuntu-2604.pkr.hcl
|
||||
@echo "✓ Build complete"
|
||||
|
||||
build-qemu: init
|
||||
@echo "==> Building zROC image v$(VERSION) with QEMU builder"
|
||||
cd $(PACKER_DIR) && PACKER_LOG=1 packer build \
|
||||
-only="qemu.ubuntu2604" \
|
||||
-var "vm_version=$(VERSION)" \
|
||||
-var-file=variables.pkrvars.hcl \
|
||||
ubuntu-2604.pkr.hcl
|
||||
|
||||
package:
|
||||
@echo "==> Packaging OVF to OVA"
|
||||
@OVF=$$(find $(OUTPUT_DIR)/vmware -name "*.ovf" | head -1); \
|
||||
if [ -z "$$OVF" ]; then echo "No OVF found in $(OUTPUT_DIR)/vmware"; exit 1; fi; \
|
||||
ovftool --compress=9 "$$OVF" "$(OUTPUT_DIR)/$(OVA_NAME)"
|
||||
@echo "✓ OVA: $(OUTPUT_DIR)/$(OVA_NAME)"
|
||||
|
||||
checksum:
|
||||
@cd $(OUTPUT_DIR) && sha256sum $(OVA_NAME) > $(OVA_NAME).sha256
|
||||
@echo "✓ Checksum: $(OUTPUT_DIR)/$(OVA_NAME).sha256"
|
||||
@cat $(OUTPUT_DIR)/$(OVA_NAME).sha256
|
||||
|
||||
verify:
|
||||
@cd $(OUTPUT_DIR) && sha256sum -c $(OVA_NAME).sha256
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTPUT_DIR)
|
||||
@echo "✓ Output directory cleaned"
|
||||
|
||||
help:
|
||||
help: ## Show available targets
|
||||
@echo ""
|
||||
@echo " zroc-ova build targets"
|
||||
@echo " ──────────────────────────────────────────"
|
||||
@grep -E '^## ' Makefile | sed 's/## / make /'
|
||||
@echo " ────────────────────────────────────────"
|
||||
@grep -E '^[a-zA-Z_-]+:.*## ' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " make %-15s %s\n", $$1, $$2}'
|
||||
@echo ""
|
||||
@echo " VERSION=$(VERSION) (override: make build VERSION=1.1.0)"
|
||||
@echo ""
|
||||
|
||||
init: ## Install required Packer plugins
|
||||
cd $(PACKER_DIR) && packer init ubuntu-2404.pkr.hcl
|
||||
|
||||
validate: ## Validate Packer config
|
||||
cd $(PACKER_DIR) && packer validate \
|
||||
-var "vm_version=$(VERSION)" \
|
||||
-var-file=variables.pkrvars.hcl \
|
||||
ubuntu-2404.pkr.hcl
|
||||
|
||||
build: validate ## Build OVA + qcow2 appliance images
|
||||
cd $(PACKER_DIR) && packer build \
|
||||
-var "vm_version=$(VERSION)" \
|
||||
-var-file=variables.pkrvars.hcl \
|
||||
ubuntu-2404.pkr.hcl
|
||||
@echo ""
|
||||
@echo "Artifacts:"
|
||||
@ls -lh $(OUTPUT_DIR)/$(ARTIFACT_PFX).ova $(OUTPUT_DIR)/$(ARTIFACT_PFX).qcow2 2>/dev/null
|
||||
@echo ""
|
||||
@cat $(OUTPUT_DIR)/$(ARTIFACT_PFX).ova.sha256 $(OUTPUT_DIR)/$(ARTIFACT_PFX).qcow2.sha256 2>/dev/null
|
||||
|
||||
clean: ## Remove all build artifacts
|
||||
rm -rf $(OUTPUT_DIR)/qemu $(OUTPUT_DIR)/$(VM_NAME)-*
|
||||
@echo "Build artifacts cleaned"
|
||||
|
||||
docker-build: ## Build zroc-ui Docker image
|
||||
cd ../zroc-ui && docker build --network=host \
|
||||
-t recklessop/zroc-ui:stable \
|
||||
-t recklessop/zroc-ui:$(VERSION) \
|
||||
-t recklessop/zroc-ui:latest \
|
||||
.
|
||||
|
||||
docker-push: ## Push zroc-ui Docker image to Docker Hub
|
||||
docker push recklessop/zroc-ui:stable
|
||||
docker push recklessop/zroc-ui:$(VERSION)
|
||||
docker push recklessop/zroc-ui:latest
|
||||
|
||||
@@ -30,8 +30,23 @@ cat << 'BANNER'
|
||||
BANNER
|
||||
echo -e "${RESET}"
|
||||
|
||||
# Step 1: Network
|
||||
step "1/6 Network Configuration"
|
||||
# Step 0: Change default zroc password
|
||||
step "1/7 Change Appliance Password"
|
||||
echo "The default 'zroc' user password must be changed."
|
||||
while true; do
|
||||
read -rsp "New password for 'zroc' (min 8 chars): " NEW_PW; echo
|
||||
read -rsp "Confirm password: " NEW_PW2; echo
|
||||
if [[ "$NEW_PW" != "$NEW_PW2" ]]; then err "Passwords do not match.";
|
||||
elif [[ ${#NEW_PW} -lt 8 ]]; then err "Password must be at least 8 characters.";
|
||||
else
|
||||
echo "zroc:$NEW_PW" | chpasswd
|
||||
ok "Appliance password changed"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Step 2: Network
|
||||
step "2/7 Network Configuration"
|
||||
CURRENT_IP=$(hostname -I | awk '{print $1}')
|
||||
echo "Current IP: ${BOLD}$CURRENT_IP${RESET} (DHCP)"
|
||||
read -rp "Keep DHCP? [Y/n]: " NET_CHOICE
|
||||
@@ -40,13 +55,13 @@ PUBLIC_URL="https://$CURRENT_IP"
|
||||
ok "Using $CURRENT_IP"
|
||||
|
||||
# Step 2: TLS
|
||||
step "2/6 HTTPS / TLS Certificate"
|
||||
step "3/7 HTTPS / TLS Certificate"
|
||||
echo "Using self-signed certificate (default)"
|
||||
TLS_MODE="internal"
|
||||
ok "Self-signed certificate will be generated by Caddy"
|
||||
|
||||
# Step 3: Admin password
|
||||
step "3/6 zROC Admin Account"
|
||||
step "4/7 zROC Admin Account"
|
||||
while true; do
|
||||
read -rsp "Admin password (min 12 chars): " ADMIN_PASS; echo
|
||||
read -rsp "Confirm password: " ADMIN_PASS2; echo
|
||||
@@ -56,18 +71,18 @@ while true; do
|
||||
done
|
||||
|
||||
# Step 4: ZVM Site 1
|
||||
step "4/6 Zerto ZVM Configuration — Site 1"
|
||||
step "5/7 Zerto ZVM Configuration — Site 1"
|
||||
read -rp "ZVM Hostname or IP: " ZVM_HOST
|
||||
read -rp "ZVM Username [admin]: " ZVM_USER; ZVM_USER="${ZVM_USER:-admin}"
|
||||
read -rsp "ZVM Password: " ZVM_PASS; echo
|
||||
read -rp "vCenter Hostname (optional): " VCENTER_HOST
|
||||
|
||||
# Step 5: Second site
|
||||
step "5/6 Second ZVM Site (optional)"
|
||||
step "6/7 Second ZVM Site (optional)"
|
||||
read -rp "Monitor a second site? [y/N]: " SITE2; SITE2="${SITE2:-N}"
|
||||
|
||||
# Step 6: Enterprise IdP
|
||||
step "6/6 Enterprise Identity Provider (optional)"
|
||||
step "7/7 Enterprise Identity Provider (optional)"
|
||||
echo "Using local Authentik accounts (default)"
|
||||
|
||||
# Generate secrets
|
||||
@@ -105,7 +120,9 @@ echo "Starting zROC services..."
|
||||
cd "$INSTALL_DIR"
|
||||
docker compose up -d 2>&1 | tail -20
|
||||
|
||||
systemctl disable zroc-firstboot.service 2>/dev/null || true
|
||||
# Remove the getty override so normal login resumes after reboot
|
||||
rm -f /etc/systemd/system/getty@tty1.service.d/zroc-firstboot.conf
|
||||
systemctl daemon-reload
|
||||
|
||||
echo -e "${GREEN}${BOLD}"
|
||||
echo " ✅ zROC is ready!"
|
||||
|
||||
@@ -10,29 +10,20 @@ autoinstall:
|
||||
id: ubuntu-server-minimal
|
||||
|
||||
storage:
|
||||
layout:
|
||||
name: direct
|
||||
config:
|
||||
- type: disk
|
||||
id: disk0
|
||||
match:
|
||||
size: largest
|
||||
ptable: gpt
|
||||
wipe: superblock-recursive
|
||||
preserve: false
|
||||
grub_device: true
|
||||
- type: partition
|
||||
id: part-efi
|
||||
id: part-bios
|
||||
device: disk0
|
||||
size: 512M
|
||||
flag: boot
|
||||
size: 1M
|
||||
flag: bios_grub
|
||||
number: 1
|
||||
preserve: false
|
||||
- type: format
|
||||
id: fmt-efi
|
||||
volume: part-efi
|
||||
fstype: fat32
|
||||
preserve: false
|
||||
- type: partition
|
||||
id: part-root
|
||||
device: disk0
|
||||
@@ -48,10 +39,8 @@ autoinstall:
|
||||
id: mnt-root
|
||||
device: fmt-root
|
||||
path: /
|
||||
- type: mount
|
||||
id: mnt-efi
|
||||
device: fmt-efi
|
||||
path: /boot/efi
|
||||
swap:
|
||||
size: 0
|
||||
|
||||
identity:
|
||||
hostname: zroc-appliance
|
||||
|
||||
@@ -8,29 +8,23 @@ echo "==> [03-setup-wizard] Installing setup wizard"
|
||||
cp -r /tmp/overlays/usr /
|
||||
chmod 0755 /usr/local/bin/zroc-setup
|
||||
|
||||
cat > /etc/systemd/system/zroc-firstboot.service << 'EOF'
|
||||
[Unit]
|
||||
Description=zROC First-Boot Setup Wizard
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
ConditionPathExists=!/opt/zroc/.env
|
||||
|
||||
# Override getty on tty1 to run the setup wizard on first boot.
|
||||
# Once .env exists the override is removed and normal getty resumes.
|
||||
mkdir -p /etc/systemd/system/getty@tty1.service.d
|
||||
cat > /etc/systemd/system/getty@tty1.service.d/zroc-firstboot.conf << 'EOF'
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/local/bin/zroc-setup
|
||||
ExecStartPre=/bin/sh -c '[ ! -f /opt/zroc/.env ] || { rm -f /etc/systemd/system/getty@tty1.service.d/zroc-firstboot.conf && systemctl daemon-reload && exit 1; }'
|
||||
ExecStart=
|
||||
ExecStart=-/usr/local/bin/zroc-setup
|
||||
StandardInput=tty
|
||||
TTYPath=/dev/tty1
|
||||
StandardOutput=journal+console
|
||||
StandardError=journal+console
|
||||
TimeoutStartSec=0
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
StandardOutput=tty
|
||||
StandardError=tty
|
||||
TTYVTDisallocate=yes
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable zroc-firstboot.service
|
||||
|
||||
rm -f /etc/sudoers.d/zroc-packer
|
||||
cat > /etc/sudoers.d/zroc << 'EOF'
|
||||
|
||||
@@ -29,6 +29,7 @@ dd if=/dev/zero of=/ZERO bs=4M status=progress 2>/dev/null || true
|
||||
rm -f /ZERO
|
||||
sync
|
||||
|
||||
# Zero swap if present (appliance is built without swap by default)
|
||||
SWAP_DEV=$(swapon --show=NAME --noheadings 2>/dev/null | head -1)
|
||||
if [[ -n "$SWAP_DEV" ]]; then
|
||||
swapoff "$SWAP_DEV"
|
||||
|
||||
Generated
+2101
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user