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
|
VERSION ?= 1.0.0
|
||||||
PACKER_DIR = packer
|
PACKER_DIR = packer
|
||||||
OUTPUT_DIR = output
|
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:
|
help: ## Show available targets
|
||||||
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:
|
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " zroc-ova build targets"
|
@echo " zroc-ova build targets"
|
||||||
@echo " ──────────────────────────────────────────"
|
@echo " ────────────────────────────────────────"
|
||||||
@grep -E '^## ' Makefile | sed 's/## / make /'
|
@grep -E '^[a-zA-Z_-]+:.*## ' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " make %-15s %s\n", $$1, $$2}'
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " VERSION=$(VERSION) (override: make build VERSION=1.1.0)"
|
@echo " VERSION=$(VERSION) (override: make build VERSION=1.1.0)"
|
||||||
@echo ""
|
@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
|
BANNER
|
||||||
echo -e "${RESET}"
|
echo -e "${RESET}"
|
||||||
|
|
||||||
# Step 1: Network
|
# Step 0: Change default zroc password
|
||||||
step "1/6 Network Configuration"
|
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}')
|
CURRENT_IP=$(hostname -I | awk '{print $1}')
|
||||||
echo "Current IP: ${BOLD}$CURRENT_IP${RESET} (DHCP)"
|
echo "Current IP: ${BOLD}$CURRENT_IP${RESET} (DHCP)"
|
||||||
read -rp "Keep DHCP? [Y/n]: " NET_CHOICE
|
read -rp "Keep DHCP? [Y/n]: " NET_CHOICE
|
||||||
@@ -40,13 +55,13 @@ PUBLIC_URL="https://$CURRENT_IP"
|
|||||||
ok "Using $CURRENT_IP"
|
ok "Using $CURRENT_IP"
|
||||||
|
|
||||||
# Step 2: TLS
|
# Step 2: TLS
|
||||||
step "2/6 HTTPS / TLS Certificate"
|
step "3/7 HTTPS / TLS Certificate"
|
||||||
echo "Using self-signed certificate (default)"
|
echo "Using self-signed certificate (default)"
|
||||||
TLS_MODE="internal"
|
TLS_MODE="internal"
|
||||||
ok "Self-signed certificate will be generated by Caddy"
|
ok "Self-signed certificate will be generated by Caddy"
|
||||||
|
|
||||||
# Step 3: Admin password
|
# Step 3: Admin password
|
||||||
step "3/6 zROC Admin Account"
|
step "4/7 zROC Admin Account"
|
||||||
while true; do
|
while true; do
|
||||||
read -rsp "Admin password (min 12 chars): " ADMIN_PASS; echo
|
read -rsp "Admin password (min 12 chars): " ADMIN_PASS; echo
|
||||||
read -rsp "Confirm password: " ADMIN_PASS2; echo
|
read -rsp "Confirm password: " ADMIN_PASS2; echo
|
||||||
@@ -56,18 +71,18 @@ while true; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Step 4: ZVM Site 1
|
# 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 Hostname or IP: " ZVM_HOST
|
||||||
read -rp "ZVM Username [admin]: " ZVM_USER; ZVM_USER="${ZVM_USER:-admin}"
|
read -rp "ZVM Username [admin]: " ZVM_USER; ZVM_USER="${ZVM_USER:-admin}"
|
||||||
read -rsp "ZVM Password: " ZVM_PASS; echo
|
read -rsp "ZVM Password: " ZVM_PASS; echo
|
||||||
read -rp "vCenter Hostname (optional): " VCENTER_HOST
|
read -rp "vCenter Hostname (optional): " VCENTER_HOST
|
||||||
|
|
||||||
# Step 5: Second site
|
# 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}"
|
read -rp "Monitor a second site? [y/N]: " SITE2; SITE2="${SITE2:-N}"
|
||||||
|
|
||||||
# Step 6: Enterprise IdP
|
# Step 6: Enterprise IdP
|
||||||
step "6/6 Enterprise Identity Provider (optional)"
|
step "7/7 Enterprise Identity Provider (optional)"
|
||||||
echo "Using local Authentik accounts (default)"
|
echo "Using local Authentik accounts (default)"
|
||||||
|
|
||||||
# Generate secrets
|
# Generate secrets
|
||||||
@@ -105,7 +120,9 @@ echo "Starting zROC services..."
|
|||||||
cd "$INSTALL_DIR"
|
cd "$INSTALL_DIR"
|
||||||
docker compose up -d 2>&1 | tail -20
|
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 -e "${GREEN}${BOLD}"
|
||||||
echo " ✅ zROC is ready!"
|
echo " ✅ zROC is ready!"
|
||||||
|
|||||||
@@ -10,29 +10,20 @@ autoinstall:
|
|||||||
id: ubuntu-server-minimal
|
id: ubuntu-server-minimal
|
||||||
|
|
||||||
storage:
|
storage:
|
||||||
layout:
|
|
||||||
name: direct
|
|
||||||
config:
|
config:
|
||||||
- type: disk
|
- type: disk
|
||||||
id: disk0
|
id: disk0
|
||||||
match:
|
|
||||||
size: largest
|
|
||||||
ptable: gpt
|
ptable: gpt
|
||||||
wipe: superblock-recursive
|
wipe: superblock-recursive
|
||||||
preserve: false
|
preserve: false
|
||||||
grub_device: true
|
grub_device: true
|
||||||
- type: partition
|
- type: partition
|
||||||
id: part-efi
|
id: part-bios
|
||||||
device: disk0
|
device: disk0
|
||||||
size: 512M
|
size: 1M
|
||||||
flag: boot
|
flag: bios_grub
|
||||||
number: 1
|
number: 1
|
||||||
preserve: false
|
preserve: false
|
||||||
- type: format
|
|
||||||
id: fmt-efi
|
|
||||||
volume: part-efi
|
|
||||||
fstype: fat32
|
|
||||||
preserve: false
|
|
||||||
- type: partition
|
- type: partition
|
||||||
id: part-root
|
id: part-root
|
||||||
device: disk0
|
device: disk0
|
||||||
@@ -48,10 +39,8 @@ autoinstall:
|
|||||||
id: mnt-root
|
id: mnt-root
|
||||||
device: fmt-root
|
device: fmt-root
|
||||||
path: /
|
path: /
|
||||||
- type: mount
|
swap:
|
||||||
id: mnt-efi
|
size: 0
|
||||||
device: fmt-efi
|
|
||||||
path: /boot/efi
|
|
||||||
|
|
||||||
identity:
|
identity:
|
||||||
hostname: zroc-appliance
|
hostname: zroc-appliance
|
||||||
|
|||||||
@@ -8,29 +8,23 @@ echo "==> [03-setup-wizard] Installing setup wizard"
|
|||||||
cp -r /tmp/overlays/usr /
|
cp -r /tmp/overlays/usr /
|
||||||
chmod 0755 /usr/local/bin/zroc-setup
|
chmod 0755 /usr/local/bin/zroc-setup
|
||||||
|
|
||||||
cat > /etc/systemd/system/zroc-firstboot.service << 'EOF'
|
# Override getty on tty1 to run the setup wizard on first boot.
|
||||||
[Unit]
|
# Once .env exists the override is removed and normal getty resumes.
|
||||||
Description=zROC First-Boot Setup Wizard
|
mkdir -p /etc/systemd/system/getty@tty1.service.d
|
||||||
After=network-online.target
|
cat > /etc/systemd/system/getty@tty1.service.d/zroc-firstboot.conf << 'EOF'
|
||||||
Wants=network-online.target
|
|
||||||
ConditionPathExists=!/opt/zroc/.env
|
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
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; }'
|
||||||
RemainAfterExit=yes
|
ExecStart=
|
||||||
ExecStart=/usr/local/bin/zroc-setup
|
ExecStart=-/usr/local/bin/zroc-setup
|
||||||
StandardInput=tty
|
StandardInput=tty
|
||||||
TTYPath=/dev/tty1
|
StandardOutput=tty
|
||||||
StandardOutput=journal+console
|
StandardError=tty
|
||||||
StandardError=journal+console
|
TTYVTDisallocate=yes
|
||||||
TimeoutStartSec=0
|
Restart=always
|
||||||
|
RestartSec=3
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable zroc-firstboot.service
|
|
||||||
|
|
||||||
rm -f /etc/sudoers.d/zroc-packer
|
rm -f /etc/sudoers.d/zroc-packer
|
||||||
cat > /etc/sudoers.d/zroc << 'EOF'
|
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
|
rm -f /ZERO
|
||||||
sync
|
sync
|
||||||
|
|
||||||
|
# Zero swap if present (appliance is built without swap by default)
|
||||||
SWAP_DEV=$(swapon --show=NAME --noheadings 2>/dev/null | head -1)
|
SWAP_DEV=$(swapon --show=NAME --noheadings 2>/dev/null | head -1)
|
||||||
if [[ -n "$SWAP_DEV" ]]; then
|
if [[ -n "$SWAP_DEV" ]]; then
|
||||||
swapoff "$SWAP_DEV"
|
swapoff "$SWAP_DEV"
|
||||||
|
|||||||
Generated
+2101
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user